Search code examples
bashawkfieldseparator

awk command in bash script replaced my file field separator from ":" to " "


This is how my BookDB.txt file looks like:

Red:Blue:12:197:101

I entered this command into the prompt:

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

And this is the changes to my file:

Red Black 12 197 101

The problem is that I want the command to preserve the field separator as ":" but the command changes the field separator to the white space. The only field that I want to change is the second field called "Blue" to "Black". Is there any way for me to preserve the separator as ":"?

This is the result I wanted:

Red:Black:12:197:101

EDITS:

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

Solution

  • When you assign a value to a field you are telling awk to recompile the current record using the current OFS value to replace the FS value that was used when the record was read. You want:

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

    The reason the above way of setting FS and OFS is the right way is that when initing 2 variables that MUST be set to the same hard-coded value, for clarity and future maintainability it's best to init them at the same time to that value instead of initing them independently to the same value in completely separate parts of the code.

    It also makes a lot more sense to init variables at the start of the script, i.e. before they are used, instead of at the end of the script after they're used.