Подсчитайте количество файлов в каталоге, содержащем две конкретные строки в bash - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть несколько файлов в каталоге, содержащем следующий шаблон:

Simulator tool completed simulation at 20:07:18 on 09/28/18.
The situation of the simulation: STATUS PASSED

Теперь я хочу подсчитать количество файлов, которые содержат обе строки completed simulation & STATUS PASSED в любом месте файла.

Эта команда работает для поиска одной строки STATUS PASSED и подсчета номеров файлов:

find /directory_path/*.txt -type f -exec grep -l "STATUS PASSED" {} + | wc -l

Sed также дает 0 в результате:

find /directory_path/*.txt -type f -exec sed -e '/STATUS PASSED/!d' -e '/completed simulation/!d' {} + | wc -l

ЛюбойПомощь / предложение будет очень ценным!

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018
find . -type f -exec \
awk '/completed simulation/{x=1} /STATUS PASSED/{y=1} END{if (x&&y) print FILENAME}' {} \; |
wc -l

Я печатаю совпадающие имена файлов на случай, если это пригодится в каком-то другом контексте, но передача этого в wc не удастся, если имена файлов содержат символы новой строки - если это так, просто напечатайте 1 или что-нибудь еще из awk.

Поскольку find /directory_path/*.txt -type f - это то же самое, что и ls /directory_path/*.txt, если все файлы ".txt" являются файлами, тем не менее, это звучит так, как будто все, что вам действительно нужно (используя GNU awk для nextfile):

awk '
    FNR==1 { x=y=0 }
    /completed simulation/ { x=1 }
    /STATUS PASSED/        { y=1 }
    x && y { cnt++; nextfile }
    END { print cnt+0 }
' /directory_path/*.txt

или с любым awk:

awk '
    FNR==1 { x=y=f=0 }
    /completed simulation/ { x=1 }
    /STATUS PASSED/        { y=1 }
    x && y && !f { cnt++; f=1 }
    END { print cnt+0 }
' /directory_path/*.txt

Они будут работать независимо от того, какие символы в именах ваших файлов.

0 голосов
/ 30 сентября 2018

Использование grep и стандартных утилит:

{ grep -Hm1 'completed simulation' /directory_path/*.txt;
  grep -Hm1 'STATUS PASSED'        /directory_path/*.txt ; } |
sort | uniq -d | wc -l

grep -m1 останавливается, когда он находит первое совпадение.Это экономит время, если это большой файл.Если список совпадений большой, sort -t: -k1 будет лучше, чем sort.

0 голосов
/ 30 сентября 2018

Команда find /directory_path/*.txt просто перечисляет все текстовые файлы в /directory_path/, не включая подкаталоги /directory_path

find . -name \*.txt -print0 |
while read -d $'\0' file; do
  grep -Fq 'completed simulation' "$file" &&
  grep -Fq 'STATUS PASSED' "$_" &&
  echo "$_"
done |
wc -l

Если вы не укажете специальных символов в именах файлов

find . -name \*.txt |
while read file; do
  grep -Fq 'completed simulation' "$file" &&
  grep -Fq 'STATUS PASSED' "$file" &&
  echo "$file"
done |
wc -l

У меня нет AIX для его тестирования, но он должен быть POSIX-совместимым.

...