По сути, все, что я хочу сделать, это изменить выходные данные, если входные данные соответствуют фильтру, но изменяемая часть не является тем, что фильтруется (иначе я бы использовал sed
). Проблема пока в том, что мой awk
выводит только измененные строки.
Быстрый пример, вставьте это в test.txt:
orange beet pear cowmilk
apple pear berry cowmilk
orange melon cherry cowmilk
Если я использую код:
awk /orange/'{gsub(/cow/,"cow~"); print}' test.txt
Я получил:
orange beet pear cow~milk
orange melon cherry cow~milk
Когда я бы предпочел получить:
orange beet pear cow~milk
apple pear berry cowmilk
orange melon cherry cow~milk
Я вижу, что можно обойтись ||
awk, но я не смог понять, как это согласовать с gsub выше.
Для дополнительной признательности я бы очень хотел добавить цвет вместо ~
, но это полностью ломает, т.е.
awk /orange/'{gsub(/cow/,"cow'\e[1;34m'"); print}' test.txt
выдает ошибку о том, что \
я не являюсь концом очереди.
решение1
Для цвета вам нужно указать фактический символ ESC (не экранированную форму \e
).. значение шестнадцатеричное \x1B
или восьмеричное \033
. Следующие скрипты раскрашивают тире -
и печатают все входные строки
awk '/orange/{gsub(/cowmilk/,"cow\x1B[1;34m-\x1B[0mmilk")} {print}' "$file"
sed '/orange/{s/cowmilk/cow\x1B[1;34m-\x1B[0mmilk/g}' "$file"
решение2
Для печати каждой строки после изменения лишь нескольких из них добавьте отдельное условие, которое всегда оценивается как истинное, например ( 1
):
awk '/orange/{gsub("cow", "cow~")} 1' "$file"
Вы также могли бы {print}
явно указать:
awk '/orange/{gsub("cow", "cow~")} {print}' "$file"
Помните, что каждый оператор awk состоит из условия и предложения оператора:
condition {statements}
Но каждый из них является необязательным, если вы не включите{statements}
, то {print}
используется. Если вы не включаетеcondition
, затем 1
используется.