Ответ 1
Как насчет этого:
grep -o -c Hello * | awk -F: '{if ($2 > 1){print $1}}'
Мне нужно найти файлы, где определенная строка появляется дважды или более.
Например, для трех файлов:
Файл 1:
Hello World!
Файл 2:
Hello World!
Hello !
Файл 3:
Hello World!
Hello
Hello Again.
-
Я хочу grep Hello
и получить файлы 2
и 3
.
Как насчет этого:
grep -o -c Hello * | awk -F: '{if ($2 > 1){print $1}}'
Поскольку вопрос помечен grep
, вот решение, использующее только эту утилиту и bash
(не требуется awk
):
#!/bin/bash
for file in *
do
if [ "$(grep -c "Hello" "${file}")" -gt 1 ]
then
echo "${file}"
fi
done
Может быть однострочным:
for file in *; do if [ "$(grep -c "Hello" "${file}")" -gt 1 ]; then echo "${file}"; fi; done
for file in *
с помощью любого расширения оболочки, которое вы хотите получить для всех файлов данных.grep -c
возвращает количество строк, соответствующих шаблону, с несколькими совпадениями в строке, все еще считающейся только для одной строки.if [ ... -gt 1 ]
проверьте, что в файле сопоставляется более одной строки. Если да:echo ${file}
напечатать имя файла.Вам понадобится grep
, который может распознавать шаблоны в конце строки ( "привет", за которым следует что-либо (возможно, даже окончание строки), а затем "привет" )
Поскольку grep
обрабатывает ваши файлы по строкам, он (сам по себе) не является правильным инструментом для задания - если только вам не удастся втиснуть весь файл в одну строку.
Теперь это легко, например, с помощью команды tr
, заменяя окончания строки пробелами:
if cat $file | tr '\n' ' ' | grep -q 'hello.*hello'
then
echo "$file matches"
fi
Это довольно эффективно даже в больших файлах со многими (скажем, 100000) линиями и может быть еще более эффективным, вызывая grep
с помощью --max-count=1
, что позволяет остановить поиск после того, как совпадение найдено. Не имеет значения, находятся ли два hellos в одной строке или нет.
Этот awk
будет печатать имя файла всех файлов с 2
или более Hello
awk 'FNR==1 {if (a>1) print f;a=0} /Hello/ {a++} {f=FILENAME} END {if (a>1) print f}' *
file2
file3
После прочтения вашего вопроса, я думаю, вы также захотите найти случай hello hello
в одной строке. (find files where a specific string appears twice or more.
), поэтому я придумываю этот однострочный слой:
awk -v p="hello" 'FNR==1{x=0}{x+=gsub(p,p);if(x>1){print FILENAME;nextfile}}' *
p
- это шаблон, который вы хотите искатьНебольшой тест:
kent$ head f*
==> f <==
hello hello world
==> f2 <==
hello
==> f3 <==
hello
hello
SK-Arch 22:27:00 /tmp/test
kent$ awk -v p="hello" 'FNR==1{x=0}{x+=gsub(p,p);if(x>1){print FILENAME;nextfile}}' f*
f
f3
grep -c Привет * | egrep -v ': [01] $' | sed 's/: [0-9] * $//'
Другой способ:
grep Hello * | cut -d: -f1 | uniq -d
Grep для строк, содержащих "Hello"; сохраняйте только имена файлов; напечатайте только дубликаты.
Передача на язык сценариев может быть излишней, но зачастую это намного проще, чем просто использовать awk
grep -rnc "Hello" . | ruby -ne 'file, count = $_.split(":"); puts "#{file}: #{count}" if count&.to_i >= 2'
Так что за ваш вклад мы получаем
$ grep -rnc "Hello" . | ruby -ne 'file, count = $_.split(":"); puts "#{file}: #{count}" if count&.to_i >= 2'
./2: 2
./3: 3
Или опустить счет
grep -rnc "Hello" . | ruby -ne 'file, _ = $_.split(":"); puts file if count&.to_i >= 2'