Есть ли способ одновременно использовать две разные ссылки на файлы в циклах for? Что-то типа:
for file in file1 file2 file3; for name in name1 name2 name3
do
awk 'FNR==NR{a[$1];next};($1 in a)' ${file}.txt ${name}.txt > ${name}_extract.txt
done
Я также пробовал с вложенным циклом for, который не работал:
for file in file1 file2 file3
do
for name in name1 name2 name3
do
awk 'FNR==NR{a[$1];next};($1 in a)' ${file}.txt ${name}.txt > ${name}_extract.txt
done
done
Чего я хотел бы добиться, так это извлечь строки из «file1.txt» и «name1.txt», которые соответствуют их первому столбцу. И наоборот для файла2.txt/имя2.txt и файла3.txt/имя3.txt.
В будущем, когда у вас будет ошибка сценария оболочки, хорошим первым шагом будет вырезать и вставить ваш код в shellcheck.net и исправить ошибки (важные) и предупреждения (могут быть важными), которые он идентифицирует. Если у вас есть проблемы с пониманием его сообщений, зайдите сюда и спросите.
@John1024 John1024 Да, я пропустил одно утверждение do, хотя оно все еще не работает, см. редактирование. Он не выдает ошибок, но все выходные файлы, кроме одного, пусты.
Вы пытаетесь перебрать все комбинации переменных (например, «файл1» и «имя1», затем «файл1» и «имя2», затем «файл1» и «имя3», затем «файл2» и «имя1» и т. д.) или сразу над соответствующими элементами (т.е. просто «файл1» и «имя1», затем «файл2» и «имя2», затем «файл3» и «имя3»)? Две петли дадут вам все комбинации; если вам нужны только соответствующие элементы, вам нужен один цикл (и, возможно, элементы в массивах).





Если файлы и имена действительно называются file1, file2, file3 и name1, name2 и name3, то можно сделать примерно так:
for i in {1..3}; do
printf '%s\n' "file: file$i, name: name$i"
done
Вы заменяете оператор printf тем, что вам нужно — важная часть — это то, как вы получаете доступ к файлам и именам.
Однако, если они имеют произвольные имена, вам нужно сделать что-то вроде подготовки двух массивов, а затем выполнить цикл по индексам:
files=(file1 file2 file3)
names=(name1 name2 name3)
for (( i = 0; i < ${#files[@]}; ++i )); do
printf '%s\n' "file: ${files[i]}, name: ${names[i]}"
done
Из вопроса неясно, хотите ли вы запустить 3 итерации или 9. Если вы хотите только 3 итерации, мне нравится формат:
while read file name; do
...
done << EOF
file1 name1
file2 name2
file3 name3
EOF
Отлично, спасибо @William Pursell, это прекрасно работает!
Для двух циклов
forтребуются операторы дваdo. Вам не хватает одного.