У меня есть следующие три файла
**file_01.sh**
GOOD_word
bla bla BAD_word
miao GOOD_word bau
BAD_word
GOOD_word foo
**file_02.sh**
GOOD_word yes
GOOD_word bla bla BAD_word
GOOD_word bla
BAD_word
**file_03.sh**
just BAD_word
and bla bla
Я бы хотел получить следующий результат:
**“o_file.txt”:**
./i_dir/file_01.sh:1:GOOD_word
./i_dir/file_01.sh:3:miao GOOD_word bau
./i_dir/file_01.sh:5:GOOD_word foo
./i_dir/file_02.sh:1:GOOD_word yes
./i_dir/file_02.sh:3:GOOD_word bla
Это то, что я пробую пока , но не работает.
find ./dir -type f -exec grep -E -i -H "GOOD_word" {} \; |
grep -v “BAD_word” {} \; >> o_file.txt;
Вы близки - вам просто нужно добавить -n
для номера строк и удалите второй {}
, чтобы grep -v
работал с выводом первого grep, а не с найденными файлами:
$ find ./i_dir -type f -exec grep -E -i -H -n "GOOD_word" {} \; | grep -v "BAD_word"
./i_dir/file_01.sh:1:GOOD_word
./i_dir/file_01.sh:3:miao GOOD_word bau
./i_dir/file_01.sh:5:GOOD_word foo
./i_dir/file_02.sh:1:GOOD_word yes
./i_dir/file_02.sh:3:GOOD_word bla
Я предполагаю что вам нужно -E
, потому что ваше «настоящее» GOOD_word
является расширенным регулярным выражением - если это не так, вы можете его опустить (и, возможно, также -i
).
В качестве альтернативы вы можете сделать что-то вроде этого, используя bash globstar для спуска каталога и awk для логики:
shopt -s globstar
awk '/GOOD_word/ && !/BAD_word/{print FILENAME,FNR,$0}' OFS=: ./i_dir/**/*
См. Также
Вам не нужно найти
! ... grep
имеет параметр для этого:
-r, --recursive Рекурсивно читать все файлы в каждом каталоге, переходя по символическим ссылкам, только если они находятся в командной строке. Обратите внимание: если файловый операнд не указан, grep ищет рабочий каталог. Это эквивалентно опции -d recurse.
или
-R, --dereference-recurse Рекурсивно считывать все файлы в каждом каталоге. Перейти по всем символическим ссылкам, В отличие от -r.
Дополнительные параметры находятся в man grep
Вы можете выполнить следующее из каталога, содержащего три файла.
Чтобы исключить только слово BAD_word
:
sed 's/BAD_word//' <(grep -rwn "GOOD_word" .)
или исключить целые строки, содержащие слово BAD_word
:
grep -wv "BAD_word" <(grep -rwn "GOOD_word" .)