Skip to content
Advertisement

Unix – Replace column value inside while loop

I have comma separated (sometimes tab) text file as below:

parameters.txt:

STD,ORDER,ORDER_START.xml,/DML/SOL,Y
STD,INSTALL_BASE,INSTALL_START.xml,/DML/IB,Y

with below code I try to loop through the file and do something

while read line; do
if [[ $1 =  "$(echo "$line" | cut -f 1)" ]] && [[ "$(echo "$line" | cut -f 5)" = "Y"  ]] ; then
//do something...
if [[ $? -eq 0 ]] ; then
// code to replace the final flag
fi
fi
done < <text_file_path>

I wanted to update the last column of the file to N if the above operation is successful, however below approaches are not working for me:

  1. sed 's/$f5/N/'
  2. '$5=="Y",$5=N;{print}'
  3. $(echo "$line" | awk '$5=N')

Update: Few considerations which need to be considered to give more clarity which i missed at first, apologies!

  1. The parameters file may contain lines with last field flag as “N” as well.
  2. Final flag needs to be update only if “//do something” code has successfully executed.
  3. After looping through all lines i.e, after exiting “while loop” flags for all rows to be set to “Y”

Advertisement

Answer

with bash:

(
IFS=,
while read -ra fields; do
    if [[ ${fields[0]} == "$1" ]] && [[ ${fields[4]} == "Y" ]]; then
        # do something
        fields[4]="N"
    fi
    echo "${fields[*]}"
done < file | sponge file
)

I run that in a subshell so the effects of altering IFS are localized.

This uses sponge to write back to the same file. You need the moreutils package to use it, otherwise use

done < file > tmp && mv tmp file

Perhaps a bit simpler, less bash-specific

while IFS= read -r line; do
    case $line in 
        "$1",*,Y) 
            # do something
            line="${line%Y}N"
            ;; 
    esac
    echo "$line"
done < file
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement