Команда awk в сценарии bash заменила мой разделитель полей файла с: на

Вот как выглядит мой файл BookDB.txt:

Red:Blue:12:197:101

Я ввел эту команду в приглашение:

awk -F: '$1=="Red"{$2="Black"}1' BookDB.txt >> tmp && mv tmp BookDB.txt

И это изменения в моем файле:

Red Black 12 197 101

Проблема в том, что я хочу, чтобы команда сохраняла разделитель полей как «:», но команда меняет разделитель полей на пробел. Единственное поле, которое я хочу изменить, это второе поле с именем «Синий» на «Черный». Есть ли способ сохранить разделитель как «:»?

Это результат, который я хотел:

Red:Black:12:197:101

РЕДАКТИРОВАНИЕ:

read -p "Title of the old book: " title
read -p "Title of the book you want to update: " title_Update

awk -F: -vOFS=":" '$1=="$title"{$1="$title_Update"}1' BookDB.txt

person Alex Gosling    schedule 19.01.2016    source источник
comment
-vOFS=":" должен сделать это, в будущем обращайтесь к справочной странице, где это четко описано.   -  person 123    schedule 19.01.2016
comment
Спасибо, это работает! Но если бы я заменил красный и черный переменными, это не так. Есть ли причина, почему?   -  person Alex Gosling    schedule 19.01.2016
comment
показать пример того, что вы имеете в виду.   -  person 123    schedule 19.01.2016
comment
Я разместил пример в столбце редактирования.   -  person Alex Gosling    schedule 19.01.2016
comment
Вы не можете использовать переменные оболочки внутри скрипта awk. Преобразуйте их в переменные awk, используя -vTitle="$title" и т. д. Опять же, это можно узнать, просто выполнив поиск вашей проблемы, например, как использовать переменные оболочки в awk   -  person 123    schedule 19.01.2016
comment
Хорошо, большое спасибо! Принято к сведению!   -  person Alex Gosling    schedule 19.01.2016
comment
Обратите внимание, что, не оставляя пробела между -v и именем переменной, вы делаете свой сценарий совершенно излишне специфичным для gawk. Просто используйте -v var=val, а не -vvar=val.   -  person Ed Morton    schedule 19.01.2016


Ответы (3)


Когда вы присваиваете значение полю, вы говорите awk перекомпилировать текущую запись, используя текущее значение OFS, чтобы заменить значение FS, которое использовалось при чтении записи. Ты хочешь:

awk -v old="$title" -v new="$title_update" 'BEGIN{FS=OFS=":"} $1==old{$1=new} 1'

Причина, по которой приведенный выше способ установки FS и OFS является правильным, заключается в том, что при инициализации двух переменных, которые ДОЛЖНЫ быть установлены на одно и то же жестко закодированное значение, для ясности и удобства сопровождения в будущем лучше вместо этого инициализировать их одновременно с этим значением. независимой инициализации их одним и тем же значением в совершенно разных частях кода.

Также имеет смысл инициализировать переменные в начале скрипта, то есть до их использования, а не в конце скрипта после их использования.

person Ed Morton    schedule 19.01.2016

Используйте ОФС:

awk -F":" '$1=="Red"{$2="Black"}1'  OFS=":" file
person Guru    schedule 19.01.2016

Вам необходимо использовать предопределенную переменную AWK OFS (разделитель полей вывода). Начальное значение этой переменной равно " ", и именно по этой причине вы получаете пробел между своим выводом. Ниже приведены различные способы использования переменной OFS.

[root@saltmaster test]# awk -F: 'BEGIN{OFS=":"}$1=="Red"{$2="Black"}1' input.txt
Red:Black:12:197:101
[root@saltmaster test]# awk -v FS=":" -v OFS=":" '$1=="Red"{$2="Black"}1' input.txt
Red:Black:12:197:101
[root@saltmaster test]# awk 'BEGIN{FS=":"; OFS=":"}$1=="Red"{$2="Black"}1' input.txt
Red:Black:12:197:101
[root@saltmaster test]# awk -F":" '$1=="Red"{$2="Black"}1'  OFS=":" input.txt
Red:Black:12:197:101
person Manish R    schedule 19.01.2016