$ grep -x -f <(sed 's/\./\\./g;s/^/.*/' listB) <(grep -v -F -x -f listB listA)
.best.co
.test.server.cloud.us-east.amazonaws.com
.abc.com.co
.def.museum.hiroshima.jp
.xyz.xxx.yyy.net
Объяснение в виде двух команд:
1.)grep -v -F -x -f listB listA
Удалите литеральные дубликаты из listA
и используйте этот вывод в качестве ввода второго grep
. Это оставляет эти записиlistA
:
.best.co
.test.server.cloud.us-east.amazonaws.com
.abc.com.co
.def.museum.hiroshima.jp
.xyz.xxx.yyy.net
.exe
.xyz.exe
(Оставшиеся строки для удаления:.exe
и.xyz.exe
)
2.)grep -x -f <(sed 's/\./\\./g;s/^/.*/' listB) <(...)
Избегайте точек .
в listB
, добавьте .*
в начало и снова grep
, чтобы сопоставить эти строки, заканчивающиеся строкой в listB
. Ввод является результатом первого grep
.
Когда вы изменяете данные и значения, вы можете достичь своей цели с помощью многомерных -массивов:
data=( a b a1 b1 c1 d1 )
arrnum=2
len=${#data[@]}
declare -i i=0
while [ "$len" -gt "$((i*arrnum))" ]; do
for (( j=0; j<$arrnum-1; j++ )); do
printf " %s " "${data[i*arrnum+j]}"
done
printf " %s\n" "${data[i*arrnum+j]}"
((i++))
done
exit 0
результат:
Поскольку в bash
нет такой вещи, как список списков, мы предположим, что вы хотите перебрать два списка попарно в цикле, что, по-видимому, также указывает ваш код. Кроме того, мы будем предполагать, что два списка всегда содержат одинаковое количество элементов и что эти списки не являются разреженными.
Вы можете написать свой цикл для итерации с индексами или с самими элементами.
Ниже приведен пример перебора индексов одного из массивов и использования его для доступа к элементам обоих массивов.
a1=( a a1 c1 )
a2=( b b1 d1 )
for i in "${!a1[@]}"; do
printf 'Pair: (%s,%s)\n' "${a1[i]}" "${a2[i]}"
done
Выражение "${!a1[@]}"
расширится до списка, содержащего индексы массива a1
.
Вы также можете использовать элементы массивов непосредственно в цикле.
a1=( a a1 c1 )
a2=( b b1 d1 )
set -- "${a1[@]}"
for b in "${a2[@]}"; do
a=$1; shift
printf 'Pair: (%s,%s)\n' "$a" "$b"
done
Здесь мы устанавливаем список позиционных параметров для элементов из массива a1
, используя set
, а затем циклически перебираем элементы другого массива. Значение $b
— это элемент из a2
в цикле, а $1
— первый позиционный параметр (— следующий элемент изa1
). Это значение $1
присваивается a
, а затем удаляется из списка позиционных параметров.
Оба приведенных выше фрагмента кода будут генерировать один и тот же результат.
Pair: (a,b)
Pair: (a1,b1)
Pair: (c1,d1)
Основная проблема с кодом, который вы показываете, заключается в том, что вы не знаете, пришли ли вы к концу массива, когда встречаете пустой элемент. Пустые элементы разрешены и должны быть разрешены в массиве. Синтаксис с -a
внутри [... ]
лучше избегать и заменять на [... ] && [... ]
из-за возможной неоднозначности, и вам также следует протестировать с -n
для непустых строк -.