2015-01-01 2 views
0

Я хочу удалить все строки в файле, который содержит один шаблон, но не другой.sed - удалить все строки, содержащие один шаблон, но не другой

Например, если у меня есть этот файл:

hello people foo 
hello world bar 
hello something 
blah blah blah 

Я хочу, чтобы удалить все строки, содержащие hello, но не world, так что мой файл выглядит следующим образом:

hello world bar 
blah blah blah 

I попробовал следующее:

sed -n '/hello/p' file | sed -i '/world/!d' 

Но я получаю сообщение об ошибке

ответ

4

альтернативу AWK:

awk '!/hello/ ||/world/' file 
+0

К сожалению, ответы sed не сработали для меня, поэтому я реализовал этот – Bolboa

+0

. Это не изменяет файл, а просто возвращает результат. Как сохранить его в файл? – BigDong

+0

@BigDong 'awk '...' file> hello.tmp && mv hello.tmp file' – Kent

4

Это должно работать

sed -i '/hello/{/world/!d}' file 
+0

по какой-то причине это не так, у меня есть файл с именем мерзавец, и Я запускаю команду sed так: sed -i '/ hello/{/ world /! D}' git ... и я получаю эту ошибку: sed: 1: "git": дополнительные символы в конце команды g – Bolboa

+1

Аналогичные результаты, такие как @Bolboa здесь, но ошибка 'sed: 1:" testfile.txt ": undefined label 'estfile.txt''. Протестировано на OS X 10.9.5. –

0
sed -i.bak '/hello/{/world/!d} 

этот ответ отличается, так как расширение предоставляется -i.

я ниже нить должна быть полезной

sed command with -i option failing on Mac, but works on Linux

+0

Это то же самое, что и 1_CR за 20 минут до вас. – Jotne

+0

@ Jotne Да .. Я думаю, что -i без расширения может быть причиной того, почему OP получает ошибку, используя это простое решение (предположение, поскольку у меня нет OS X). Небольшая разница. – repzero

5

Один СЕПГ призывание:

sed -n '/hello/ {/world/d; p}' file 

Для линий, соответствующих /hello/, если она также соответствует /world/ удалить, иначе печать

+0

hmmm ... это ошибка, которую я получаю: sed: 1: "/ hello/{/ world/d; p}": дополнительные символы в конце команды p ... Любая причина? – Bolboa

+0

Отличное решение glenn. @Bolboa, проверьте ваш синтаксис, отлично работал на Linux точно так же, как 'sed -n '/ hello/{/ world/d; p} '' –

+0

это не печатает строку' blah blah blah ' – repzero

1

Просто используйте awk, чтобы сохранить логику просто как указано:

$ awk '/hello/ && !/world/{next} 1' file 
hello world bar 
blah blah blah 
0

После игры вокруг немного, я был в состоянии обеспечить один сценарий, реализующий sed, который работал для меня:

file=$1 
patt=$(sed -n '/world/p' $file) 
sed -n "/hello/!p;/$patt/p" $file 
Смежные вопросы