Заменить слово строки, если найдено
Мне дали файл. Если строка имеет "xxx" в качестве третьего слова, то мне нужно заменить его на "yyy". Мой окончательный вывод должен иметь все исходные строки с измененными строками.Входной файл
abc xyz mno
xxx xyz abc
abc xyz xxx
abc xxx xxx xxx
Требуемый выходной файл должен быть-
abc xyz mno
xxx xyz abc
abc xyz yyy
abc xxx yyy xxx
Я пытался-
grep "\bxxx\b" file.txt | awk '{if ($3=="xxx") print $0;}' | sed -e 's/[^ ]*[^ ]/yyy/3'
но это дает выход как
abc xyz yyy
abc xxx yyy xxx
4 ответа
После простого awk
может помочь вам в том же.
awk '$3=="xxx"{$3="yyy"} 1' Input_file
Вывод будет следующим.
abc xyz mno
xxx xyz abc
abc xyz yyy
abc xxx yyy xxx
Пояснение: Проверка состояния здесь, если $3
3-е поле равно строке xxx
затем настройка $3
значение в строку yyy
, Тогда упомяну 1
там, так как awk
работает по методу условия, а затем по действию. Я ставлю условие ИСТИНА здесь, упоминая 1
здесь и НЕ упоминать какие-либо действия здесь, так что будет печать текущей строки по умолчанию (либо с измененным 3-м полем, либо с новым 3-м полем).
sed
решение:
sed -E 's/^(([^[:space:]]+[[:space:]]+){2})apathy\>/\1empathy/' file
Выход:
abc xyz mno
apathy xyz abc
abc xyz empathy
abc apathy empathy apathy
Чтобы изменить файл на месте добавить -i
опция: sed -Ei ....
Ravinder уже предоставил вам самое короткое решение для awk.
В sed будет работать следующее:
sed -E 's/(([^ ]+ ){2})xxx/\1yyy/'
Или если ваш сед не включает -E
Вы можете использовать более болезненную запись BRE:
sed 's/\(\([^ ][^ ]* \)\{2\}\)xxx/\1yyy/'
И если у вас есть настроение справиться с этим в одиночку, может что-то подобное:
while read -r line; do
read -r -a a <<<"$line"
[[ "${a[2]}" == "xxx" ]] && a[2]="yyy"
printf '%s ' "${a[@]}"
printf '\n'
done < input.txt
В общем то awk
команда может выглядеть так
awk '{command set 1}condition{command set 2}' file
command set 1
будет выполняться для каждой строки в то время как command set 2
будет выполнено, если условие, предшествующее этому, является истинным.
Мой окончательный вывод должен иметь все исходные строки с измененными строками
В твоем случае
awk 'BEGIN{print "Original File";i=1}
{print}
$3=="xxx"{$3="yyy"}
{rec[i++]=$0}
END{print "Modified File";for(i=1;i<=NR;i++)print rec[i]}'file
должен решить это.
объяснение
$3
третье разделенное пробелами поле в awk
, Если это соответствует "xxx"
затем он заменяется. Сначала выведите неизмененные строки, сохраняя измененные строки в массиве. В конце выведите измененные строки. BEGIN
а также END
блоки выполняются только в начале и конце соответственно. NR
является встроенной переменной awk, которая обозначает количество записей, обработанных до настоящего момента. Так как он используется в END
Блок это должно дать нам общее количество записей.
Все хорошо :-)