Команда «sed» для удаления строки, совпадающей с точной строкой в ​​первом слове - PullRequest
0 голосов
/ 18 мая 2018

Я нашел ответ на свой вопрос здесь: команда "sed" для удаления строки, которая точно соответствует строке первого слова

... но только частично, потому чтоРешение работает, только если я запрашиваю почти так же, как отвечал ответивший.

Они ответили:

 sed -i "/^maria\b/Id" file.txt

... чтобы вырезать только строку, начинающуюся со слова "Мария" внапример, это не Мария, если это не первое слово.

Я хочу выделить конкретный URL в файле, например: "cnn.com", но у меня также есть несколько адресов локальных хостов., 0.0.0.0 и оба имеют некоторые с одним пробелом впереди.Я также не хочу разбивать субдомены, такие как ads.cnn.com, чтобы код «работал», но не работает, когда я добавляю больше команд с опцией -e.Мой код, приведенный ниже, похоже, хорошо очищает вещи, за исключением того, что я не могу заставить его взломать cnn.com!Мой файл называется raw.txt

 sed -r -e 's/^127.0.0.1//' -e 's/^ 127.0.0.1//' -e 's/^0.0.0.0//' -e 's/^ 0.0.0.0//' -e '/#/d' -e '/^cnn.com\b/d' -e '/::/d' raw.txt | sort | tr -d "[:blank:]" | awk '!seen[$0]++' | grep cnn.com

Когда я запускаю grep для cnn.com, я вижу, что все cnn включают в себя тот, который мне не нужен, который на самом деле является "cnn.com".

 ads.cnn.com
 cl.cnn.com
 cnn.com <-- the one I don't want
 cnn.dyn.cnn.com
 customad.cnn.com
 gdyn.cnn.com
 jfcnn.com
 kermit.macnn.com
 metrics.cnn.com
 projectcnn.com
 smetrics.cnn.com
 tiads.sportsillustrated.cnn.com
 trumpincnn.com
 victory.cnn.com
 xcnn.com

Если я просто использую этот фрагмент кода с cnn.com, он, похоже, сработает.

 sed -r '/^cnn.com\b/d' raw.txt | grep cnn.com
 * I'm not using the "-e" option

Результат:

 ads.cnn.com
 cl.cnn.com
 cnn.dyn.cnn.com
 customad.cnn.com
 gdyn.cnn.com
 jfcnn.com
 kermit.macnn.com
 metrics.cnn.com
 projectcnn.com
 smetrics.cnn.com
 tiads.sportsillustrated.cnn.com
 trumpincnn.com
 victory.cnn.com
 xcnn.com

Мне кажется, что ничего не происходитработать, когда я строю команды вместе с опцией "-e".Мне нужна помощь в получении команды с несколькими опциями при помощи SED.

Любой совет?

Ubuntu 12 LTS и 16 LTS.
sed (GNU sed) 4.2.2

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

sed не понимает сопоставления в строках, только регулярные выражения, и до смешного трудно попытаться заставить sed действовать так, как если бы он это делал, см. Можно ли надежно избежать метасимволов регулярных выражений с помощью sed .Чтобы удалить строку с первым разделенным пробелом словом «foo» просто:

awk '$1 != "foo"' file

Чтобы удалить строки, начинающиеся с любого из «foo» или «bar», просто:

awk '($1 != "foo") && ($1 != "bar")' file

Если у вас есть больше, чем пара слов, то подход состоит в том, чтобы перечислить их все и создать индексированную ими хеш-таблицу, а затем проверить, является ли первое слово вашей строки индексом хеш-таблицы:

awk 'BEGIN{split("foo bar other word",badWords)} !($1 in badWords)' file

Если это не то, что вам нужно, отредактируйте ваш вопрос, чтобы уточнить ваши требования и включить краткий, тестируемый пример ввода и ожидаемый вывод с учетом этого ввода.

0 голосов
/ 18 мая 2018

. - это метасимвол в регулярном выражении, что означает «Совпадает с любым одним символом».Таким образом, вы случайно создали регулярное выражение, которое также поймает cnnPcom или cnn com или cnn\com.Хотя это, вероятно, работает для ваших нужд, было бы лучше быть более точным:

  sed -r '/^cnn\.com\b/d' raw.txt 

Разница здесь - обратная косая черта \ перед периодом ..Это экранирует метасимвол периода, поэтому он рассматривается как буквальный период.


Что касается ваших строк, начинающихся с пробела, вы можете перехватить их в одном регулярном выражении (Опять экранирование метасимвола периода):

  sed -r '/(^[ ]*|^)127\.0\.0\.1\b/d' raw.txt

Это (^[ ]*|^) означает строку, начинающуюся с любого количества повторяющихся пробелов ^[ ]* ИЛИ | начинается с ^, за которым следует ваше совпадение для 127.0.0.1.


И затем для их объединения вы можете использовать оператор | ИЛИ внутри паратезов, чтобы перехватить все ваши совпадения:

  sed -r '/(^[ ]*|^)(127\.0\.0\.1|cnn\.com|0\.0\.0\.0)\b/d' raw.txt

В качестве альтернативы вы можете использовать ; точка с запятой для разделения различных регулярных выражений:

  sed -r '/(^[ ]*|^)127\.0\.0\.1\b/d; /(^[ ]*|^)cnn\.com\b/d; /(^[ ]*|^)0\.0\.0\.0\b/d;' raw.txt
...