Не используйте цикл вообще. Вместо этого перечислите все файлы и используйте команду, например grep
или akw
, чтобы отфильтровать файлы между start
и stop
. printf
не будет иметь проблем Argument list too long
, так как это bash
встроенный -.
printf '%s\0' /home/me/*/file_*.txt |
grep -cEzf <(seq "$start" "$stop" | sed 's/.*/_&\.txt$/')
Здесь мы предполагаем, что у вас есть версии GNU grep
, которые могут обрабатывать нулевые байты. Это важно для безопасной обработки путей. Нулевой байт — единственный символ, который не может быть частью пути, поэтому мы можем использовать его для разделения путей.
Если у вас нет версии GNU, вы можете создать что-то, что разделяет пути символами новой строки, предполагая, что ни один из путей не содержит символ новой строки. Замените \0
на \n
и снимите флаг -z
.
Если вы измените …_*.txt
на что-то другое, возможно, вам также придется обновить команду sed
.
Ответ на пересмотренный вопрос:
awk 'NR==FNR {$1=""; afile[$2, $3, $4]=$0; next; }
(($4, $6, $8) in afile){ print $2 afile[$4, $6, $8]; }1' a.txt b.txt
Действительно для старой версии вопроса:
$ awk 'NR==FNR { afile[$2, $3, $4]=1; next; }
(($4, $6, $8) in afile){ print $2, $4,$6, $8; }1' a.txt b.txt >c.txt
прочитать a.txt
только столбцы 2, 3 и 4 в ассоциированный массив с именем afile
; затем сравните соответствующие столбцы второго файла b.txt
с 4, 6 и 8, если они были видны в массиве, поэтому выведите нужные столбцы из второго файла $1
без изменений, а остальные столбцы 4, 6 и 8 как хорошо; иначе выводить по умолчанию 1
для несовпадающих строк.
Результатc.txt
:
101 A B 580
10 101 E1 A Z1 B Z2 580 Z3
11 104 E2 C Z1 B Z2 581 Z3
107 A B 581
12 107 E3 A Z1 B Z2 581 Z3
14 111 E3 B Z1 S Z2 582 Z3
116 A B 582
15 116 E2 A Z1 B Z2 582 Z3
Но у вас проблемы с кодами:
awk 'NR==FNR{pattern[$0]; next} {if($4" "$6" "$8 in pattern) {print $0; gsub(pattern[$1],$2); print pattern[$0]}}' a.txt b.txt >> c.txt
pattern[$0]
:при этом вы добавляете каждую строку целиком в связанный массив шаблона из первого ввода " a.txt
";
Затем вы сравниваете столбцы #4, #6 и #8 с $4" "$6" "$8
из второго файла b.txt
со строками в этом массиве; они никогда не будут совпадать, так как вы сравниваете целые строки со значениями определенных столбцов, которые не существуют в вашем массиве шаблонов .
поскольку шаг 2 никогда не встречается с вашим внутренним блоком, потому что оператор if также никогда не запускается; и я не буду объяснять, что вы делаете с этим.
Сначала мы создаем регулярное выражение из 8 фрагментов/полей с запоминанием четного числа полей. Регулярное выражение основано на gnu sed с расширенным режимом регулярных выражений.
$ re='\S+ (\S+)'
$ for i in 1 2; do re="$re $re"; done
$ sed -En "/\n/{P;d;}
s/\s+/ /g;s/^ | \$//g
/(\S+ ){6}/bb
s/^\S+ //;H;d
:b;G
/^$re.*\n(\2 \3 \4 \S+)/{
s//\1 \5\n&/;P;D
}
" a.txt b.txt \
| sed -e 'n;H;2h;$!d;g'
Выход:
101 A B 580 D1
107 A B 581 D2
116 A B 582 D3
10 101 E1 A Z1 B Z2 580 Z3
12 107 E3 A Z1 B Z2 581 Z3
15 116 E2 A Z1 B Z2 582 Z3