Как я могу создать отношение один к одному между двумя циклами в bash? - PullRequest
1 голос
/ 07 апреля 2020

В сценарии bash я хочу создать взаимно-однозначное отношение между двумя циклами for, в каждом из которых переменные определены как последовательность. Например, я хочу, чтобы что-то вроде

for g in `seq 11 1 21`;do
for i in `seq 1 1 10`;do
cat >$i.txt  <<EOF
this one is $g.
EOF
done
done

привело к десяти файлам (1.txt, 2.txt, 3.txt и т. Д. c). 1.txt будет содержать «это 11». 2.txt будет содержать «это 12» Et c.

Приведенный выше пример является перестановочным, где каждое значение g действует на каждое значение i. Есть ли способ сделать так, чтобы только одно значение g действовало только на одно значение i в соответствующем порядке (ie 1 соответствует 11, 2 соответствует 12, et c)?

Любая помощь с благодарностью. Спасибо.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

Прежде чем я отвечу, есть критическая проблема с вопросом: две последовательности имеют разную длину (есть одиннадцать g значений, но только десять i значений). Либо одно из значений g должно быть пропущено, либо что-то заполнено как дополнительное значение для i. Для моего ответа я предполагаю, что g должен работать с 11 до 20, а не 21.

Если вам не нужны все комбинации, тогда вам нужен только один цикл; Хитрость заключается в том, чтобы заставить один l oop повторять обе последовательности одновременно. Есть несколько способов сделать это в bash. Одним из них является сохранение обеих последовательностей в виде массивов, а затем итерация по их индексам:

g_array=( {11..20} )   # Could also use g_array=( $(seq 11 1 20) ) here
i_array=( {1..10} )
for index in "${!g_array[@]}"; do    # The ${!arr[2]} gets the *indexes* of the array
    cat >"${i_array[index]}.txt"  <<EOF
this one is ${g_array[index]}.
EOF
done

В качестве альтернативы, поскольку это просто числовые c последовательности, для этого можно использовать структуру for ((init; test; step)):

for ((g=11,i=1; g<=20; g++,i++)); do    # Note: semicolons between parts, commas between things that happen together
    cat >"$i.txt"  <<EOF
this one is $g.
EOF
done
0 голосов
/ 07 апреля 2020
arr1=( $(seq 11 21 ))
arr2=( $(seq 1 10 ))

for idx in $(seq 0 ${#arr2[*]})
do
  file="/tmp/"${arr2[$idx]}".txt"
  echo "This one is ${arr1[$idx]} "  > $file
done

Сначала обе последовательности назначаются 2 массивам. И затем, перебирая длину 2-го массива, вы кадрируете строку и записываете в файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...