Я ищу способ сделать следующее с файлом с разделителями-каналами в UNIX для КАЖДОЙ СТРОКИ и не знаю, с чего начать:
- Поиск символа в строке текста (предполагается, что используется GREP?)
- Если нашли, то добавьте какой-нибудь текст в конец этой строки (используя SED?)
- Если не найдено, то ищите другой символ в той же строке.
- Если найдено, добавьте текст в конец строки, иначе ничего не делайте.
- ЦИКЛ ДЛЯ ВСЕХ СТРОК В ФАЙЛЕ
Буду признателен за любые указания.
решение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.