"пока читай LINE do" и проблемы с grep - PullRequest
4 голосов
/ 11 апреля 2011

У меня есть два файла.

file1.txt:  
Afghans  
Africans  
Alaskans  
...  

, где file2.txt содержит вывод wget на веб-странице, так что это большой неаккуратный беспорядок, но содержит много слов из первого списка.

Bashscript:

cat file1.txt | while read LINE; do grep $LINE file2.txt; done

Это не сработало, как ожидалось.Я удивился, почему, поэтому я повторил переменную $ LINE внутри цикла и добавил режим сна 1, чтобы я мог видеть, что происходит:

cat file1.txt | while read LINE; do echo $LINE; sleep 1; grep $LINE file2.txt; done

Вывод в терминале выглядит примерно так:

Афганцы
Африканцы
Аляски
Албанцы
Американцы
grep: Китайский: Нет такого файла или каталога
: Нет такого файла или каталога
Арабцы
Арабы
Арабы / Восточные индейцы
: Нет такого файла или каталога
Аргентинцы
Армяне
Азиат
Индейцы Азии
: Нет такого файла или каталога
file2.txt: азиатский Наруто
...

Таким образом, вы можете видеть, что он наконец нашел слово "азиат".Но почему он говорит:

Нет такого файла или каталога

?

Есть что-то странное или я что-то здесь упускаю?

Ответы [ 5 ]

5 голосов
/ 12 апреля 2011

А как же

grep -f file1.txt file2.txt
3 голосов
/ 12 апреля 2011

@ OP, во-первых, используйте dos2unix как рекомендовано.Затем используйте awk

awk 'FNR==NR{a[$1];next}{ for(i=1;i<=NF;i++){ if($i in a) {print $i} } } '  file1 file2_wget

Примечание: использование цикла while и grep внутри цикла неэффективно, поскольку для каждой итерации вам необходимо вызывать grep для файла 2.

@ OP, грубое объяснение: значения FNR и NR см. в руководстве gawk .FNR==NR{a[1];next} означает получение содержимого файла file1 в массив a.когда FNR не равен NR (что означает чтение второго файла сейчас), он проверит, находится ли каждое слово в файле в массиве a.Если это так, распечатайте.(цикл for используется для итерации каждого слова)

2 голосов
/ 11 апреля 2011

Используйте больше цитат и используйте меньше cat

while IFS= read -r LINE; do 
  grep "$LINE" file2.txt
done < file1.txt
1 голос
/ 29 января 2015

Несмотря на то, что usng awk работает быстрее, grep создает намного больше деталей с меньшими усилиями.Итак, после выдачи dos2unix используйте:

grep -F -i -n -f <file_containing_pattern> <file_containing_data_blob>

У вас будут все совпадения + номера строк (без учета регистра)

Как минимумДостаточно будет найти все слова из file_conisting_pattern:

grep -F -f <file_containing_pattern> <file_containing_data_blob>
1 голос
/ 11 апреля 2011

Помимо проблемы с цитированием, файл, который вы скачали, содержит окончания строк CRLF, которые исключают read. Используйте dos2unix для преобразования file1.txt перед итерацией по нему.

...