Я хотел бы найти в файлах строки, в которых присутствует какой-то узор и отсутствует какой-то другой. Например, мне нужно найти все файлы / строки, в том числе, loom
кроме файлов с расширением gloom
. Итак, я могу найти loom
с помощью команды:
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Теперь я хочу искать loom
исключая gloom
. Однако обе следующие команды завершились неудачно:
grep -v 'gloom' -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n 'loom' -v 'gloom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Что мне делать, чтобы достичь своей цели?
РЕДАКТИРОВАТЬ 1: Я имею в виду, чтоloom
иgloom
являются последовательностями символов (не обязательно словами). Итак, мне нужно, например,bloomberg
в выводе команды и не нужноungloomy
.
РЕДАКТИРОВАТЬ 2: Это образец моих ожиданий. Обе следующие строки находятся в выводе команды:
Я столкнулся с иконами, вырисовывающимися сквозь пелену ладана.
Arty является slooming в мрачный день.
Обе следующие строки отсутствуют в выводе команды:
Это мрачно , черт возьми, ужасно - огромные тупицы тупицы.
На юго-западе вокруг холла высоких pyntit
there is a loom in the gloom
- вы бы хотели напечатать эту строку? Просто пытаюсь понять, ищете ли вы просто линии, в которых ткацкий станок встречается не как часть мрака, или действительно хотите исключить строки, содержащие мрак, даже если ткацкий станок появляется сам по себе в другом месте линии. Поможет публикация некоторого образца ввода и ожидаемого вывода.How do I find lines containing the string "loom" where "loom" is not preceded by the letter "g"
? Если бы вы опубликовали образец ввода и желаемый результат, это очень помогло бы. Ответ на этот вопрос содержится в ответах ниже.loom
без предисловияg
. (Мне очень жаль. Я начал комментировать вчера, но так и не закончил. Случайно этот комментарий был отправлен.)Ответы:
Как насчет того, чтобы просто связать greps?
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
источник
bloomberg
в выводе команды, а не нужноungloomy
. Если бы одна строка содержала «… и bloomberg не слишком мрачен в отношении перспектив…», вы бы исключили эту строку, но она нужна (потому что if содержитbloomberg
).Другое решение без цепочки
grep
:egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
Между скобками вы исключаете символ
g
перед любым появлениемloom
, если толькоloom
это не первые символы строки.источник
Старовато, ну да ладно ...
Решение от @houbysoft, получившее наибольшее количество голосов, не будет работать, так как оно исключит любую строку со словом «мрак», даже если в нем есть слово «loom». Согласно ожиданиям OP, нам нужно включить строки с «ткацким станком», даже если в них тоже есть «мрак». Эта строка должна быть в выводе "Arty плывет в пасмурный день.", Но это будет исключено цепочкой grep, например
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
Вместо этого Bentoy13 работает лучше , чем пример регулярного выражения egrep.
egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
поскольку он будет включать в себя любую строку со словом «loom», независимо от того, есть ли в нем «мрачность» или нет. С другой стороны, если в нем есть только мрак, он не будет включать его, а это именно то поведение, которого хочет OP.
источник
Просто используйте awk, это намного проще, чем grep, позволяя четко выражать составные условия.
Если вы хотите пропустить строки, содержащие
loom
иgloom
:awk '/loom/ && !/gloom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)
или если вы хотите их распечатать:
awk '/(^|[^g])loom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)
и если на самом деле вам просто нужны строки, которые
loom
появляются как слово само по себе:awk '/\<loom\>/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)
источник
abc
иdef
иghi
в любом порядке. Теперь сравните это сawk '/abc/ && /def/ && /ghi/'
. Теперь подумайте о том, какawk '/loom/ && !/gloom/'
в ответах на этой странице записывается эквивалент grep .condition { action }
синтаксисом awks, но тогда это проще простого для любого, кто имеет опыт работы с C или другим языком на основе Algol.grep -Hn --color
:awk '/loom/ && !/gloom/ { gsub(/loom/, color("1;31") "&" color(0)); print color(35) FILENAME color(36) ":" color(32) FNR color(36) ":" color(0) $0; }; function color(c) { return "\033[" c "m"; }'
-v
- это флаг "перевернутого совпадения", так что конвейер - очень хороший способ:grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"
источник
/ * Вы могли бы выглядеть примерно так?
grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`
BACKQUOTES используются как скобки для команд, поэтому в этом случае при
-l
включении код в BACKQUOTES вернет вам имена файлов, а затем с -vn, чтобы сделать то, что вы хотели: иметь имена файлов, номера строк, а также фактические строки.ОБНОВЛЕНИЕ Или с помощью xargs
grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"
Надеюсь, это поможет.*/
Не обращайте внимания на то, что я написал выше, это чушь.
grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom" #this part gets the filenames with "loom" #this part gets the lines with "loom" #this part gets the linenumber, #filename and actual line
источник
Вы можете использовать
grep -P
(регулярное выражение perl)negative lookbehind
:grep -P '(?<!g)loom\b' ~/projects/**/trunk/src/**/*.@(h|cpp)
Я добавил
\b
границы слов.источник
\([^g]\|^\)
работает. И это не исключает строк с обоимиloom
иgloom
.not gloom
.bloomberg
в выводе команды, а не нужноungloomy
. Таким образом, границы слов контрпродуктивны.grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
источник
bloomberg
в выводе команды, а не нужноungloomy
. Если бы одна строка содержала «… а bloomberg не слишком мрачен в отношении перспектив…», вы бы удалили эту строку, но она нужна (потому что if содержитbloomberg
).Просто используйте!
grep -v
многократно.Содержание файла
[root@server]# cat file 1 2 3 4 5
Исключить строку или совпадение
[root@server]# cat file |grep -v 3 1 2 4 5
Исключить строку или сопоставить несколько
[root@server]# cat file |grep -v 3 |grep -v 5 1 2 4
источник
Вопрос: ищите «ткацкий станок», исключая «мрак».
Ответ:
grep -w 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
источник
bloomberg
в выводе команды, а не нужноungloomy
. Я не думаю, что-w
это решение этой головоломки.