Я ищу общий шаблон *** _ 23 в конце строки (но не: at_23) внутри файла, а затем пытаюсь изменить все эти выводы на \<23> в том же исходном файле ( функция вставки - это sed -i)
Я делаю :

egrep '[b-s u v w x y z ]+_[0-9]+$' sst_piso_top_c0.spf_typ_C | xargs...

но все мои попытки продолжить с sed не увенчались успехом.

Может кто-нибудь объяснить, как продолжить после xargs? Как мне передать список в sed и сказать sed обрабатывать каждый список и изменять его в одном и том же файле?

3 ответа3

0

Хорошо, чтобы соответствовать требованиям, которые вы разъяснили в комментариях под вашим вопросом, я бы разбил вещи на две части:

  1. исключить все строки, которые читаются в at_ прямо перед окончательным числом
  2. из оставшихся строк удалите подчеркивание в конце и заключите число в угловые скобки, перед которым стоит обратный слеш.

Решение для части 1 .:

Это проще всего сделать, написав регулярное выражение, которое точно соответствует тому, что нам не нужно, и затем попросив вызывающую команду вывести только те строки, которые не совпадают. Это проще всего сделать с помощью grep , поэтому давайте использовать его:

egrep -v "at_[0-9]+" sst_piso_top_c0.spf_typ_C

опция -v или --invert-match указывает grep печатать только несовпадающие строки.

Решение для части 2 .:

Это проще всего сделать с помощью команды sed s(ubstitute):

sed -r 's/_([0-9]+)$/\\<\1\\>/g'

регулярное выражение соответствует подчеркиванию и числу в конце строки. Заключив числовую часть в скобки (...) , мы можем вставить ее с \1 в разделе замены. Полные разделы замены состоят из угловых скобок с обратной косой чертой, заключающих нашу обратную ссылку на номер \\<\1\\> . Обратная косая черта должна быть экранирована другой обратной косой чертой \\ поскольку в противном случае она рассматривается как специальный escape-символ.

Собираем все вместе:

Если мы перенаправим вывод команды egrep в 1. в нашу команду sed из 2., команды sed будут использовать ее в качестве входного потока:

egrep -v "at_[0-9]+" sst_piso_top_c0.spf_typ_C | sed -r 's/_([0-9]+)$/\\<\1\\>/g' > sst_piso_top_c0.spf_typ_C.new

Обычно результаты sed отправляются на стандартный вывод, поэтому приведенная выше строка перенаправляет их в файл (> newfile). Обратите внимание, что это имя файла должно отличаться от того, из которого читает egrep , в противном случае мы перезаписываем тот же файл, из которого читаем, и в результате получаем пустой файл.

0

Может быть, я не понимаю проблему, но вам нужно только использовать sed для этого:

$ sed -ri 's/[b-suvwxyz]+_([0-9]+)$/\\<\1>/g' sst_piso_top_c0.spf_typ_C

Здесь мы используем () чтобы захватить это значение, а затем \1 чтобы напечатать его в разделе замены.

0

Нет необходимости объединять egrep и sed поскольку обе команды будут искать совпадения в файлах и либо выводить результаты (egrep), либо воздействовать на них (sed), так что будет делать только sed . Но для понимания того, почему ваша линия не сработала, я пойду с вашим примером:

Обычный вывод egrep имеет форму filename:matching_line при запуске в нескольких файлах и matching_line при запуске в одном файле, в то время как sed ожидает только имена файлов. Чтобы подавить обычный вывод egrep и печатать только имена файлов, которые содержат совпадения, используйте параметр -l .

Кроме того, вам не нужен пробел в списке символов ([...]), иначе он будет слишком жадным и будет соответствовать более чем одному слову. Линия, которая будет работать:

$ egrep -l '[b-su-z]+_[0-9]+$' sst_piso_top_c0.spf_typ_C | xargs sed -ri 's/[b-su-z]+_([0-9])+$/\\<\1>/g'

Если составная команда не работает, обычно рекомендуется запускать отдельные части самостоятельно и проверять их результаты. Кроме того, сообщения об ошибках, такие как "Нет такого файла", обычно указывают вам правильное направление (и было бы неплохо включить их в ваш отчет здесь).

Наконец, как указано выше, объединение egrep и sed не имеет смысла. Разумная линия будет

$ sed -ri 's/[b-su-z]+_([0-9])+$/\\<\1>/g' sst_piso_top_c0.spf_typ_C

Обновление: в моем регулярном выражении была опечатка, которую я исправил. Я также включил обратную ссылку на номера в матче, который изначально был включен zuazo. Из комментариев, которые вы сейчас написали, кажется более ясным, что вы не хотите заменять полное совпадение статическим выражением \<23> как я это сначала понял, но вы хотите, чтобы совпадающее число отображалось в угловых скобках ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .