Построчные модификации в Unix

Построчные модификации в Unix

Я ищу способ сделать следующее с файлом с разделителями-каналами в UNIX для КАЖДОЙ СТРОКИ и не знаю, с чего начать:

  1. Поиск символа в строке текста (предполагается, что используется GREP?)
  2. Если нашли, то добавьте какой-нибудь текст в конец этой строки (используя SED?)
  3. Если не найдено, то ищите другой символ в той же строке.
  4. Если найдено, добавьте текст в конец строки, иначе ничего не делайте.
  5. ЦИКЛ ДЛЯ ВСЕХ СТРОК В ФАЙЛЕ

Буду признателен за любые указания.

решение1

Это все sedработа, вам не понадобятся дополнительные инструменты:

Допустим, вы хотите добавить fooв конце строки, содержащей , fи barв конце строки без f, но с .b

sed '/f/{
  s/$/foo/
  b
  }
/b/s/$/bar/'

Вы можете «адресовать» строки с помощью /pattern/, поэтому следующие команды будут выполнены только в том случае, если они содержат шаблон. Таким образом, в примере только строки, содержащие , запускают fвыполнение замены sи b( {}группа команд, поэтому все внутри применяется только в случае совпадения адреса. bПереходы в конец скрипта позволяют избежать добавления еще одной строки для совпадения b.

Другой подход без ветвления:

sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'

В качестве упражнения вы можете разобраться в этом самостоятельно, обладая некоторыми sedзнаниями и используя man sedпри необходимости.

решение2

Если вы хотите добавить одну и ту же текстовую строку в конец строки для обоих сценариев (искомые символы: «X» и «Y»), то вы можете сделать это следующим образом:

sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile

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

sed -e '
   /X/s/$/__TEXT1__/; t
   /Y/s/$/__TEXT2__/
' yourfile

Где мы используем tкоманду (читается как test), чтобы определить, была ли предыдущая s///команда успешной, и перейти к концу кода sed на текущей строке. Также обратите внимание на синтаксис: /regex/s/// => если строка содержит регулярное выражение, то выполнить замену на строке.

решение3

Perl также является полезным инструментом, который позволяет легко сделать все за один раз.

Таким образом, в примере @Philippos программа на Perl будет выглядеть следующим образом (часть синтаксиса необязательна и была добавлена ​​для ясности):

perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file

Это считывает fileи выводит результат. Вы также можете «редактировать» файл на месте, используя -pi -eвместо -pe( -iозначает «на месте»), так:

perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file

Вероятно, есть способ сделать это, awkхотя первоначальное тестирование мне не удалось (я не настолько хорошо разбираюсь в AWK), с помощью Ruby (который выглядит почти так же, напишите мне, если вам нужны примеры), и это может быть весело в чистом Bash.

Связанный контент