Как перебрать список списка (вложенного списка )в bash?

$ 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.

2
02.10.2021, 23:29
2 ответа

Когда вы изменяете данные и значения, вы можете достичь своей цели с помощью многомерных -массивов:

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

результат:

1

0
03.10.2021, 03:00

Поскольку в 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для непустых строк -.

1
03.10.2021, 06:21

Теги

Похожие вопросы