Unix-在while循环内替换列值

时间:2018-09-25 18:55:27

标签: linux shell unix awk sed

我有一个逗号分隔的文本文件(有时是标签),如下所示:

parameters.txt:

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

使用以下代码,我尝试遍历文件并执行某些操作

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>

如果上述操作成功,我想将文件的最后一列更新为N,但是以下方法对我不起作用:

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

更新:抱歉,我想念的一些考虑事项不能使我更加清楚!

  1. 参数文件可能包含最后一个字段标记也为“ N”的行。
  2. 仅在成功执行“ //执行某事”代码后,才需要更新最终标志。
  3. 遍历所有行后,即退出所有行的“ while循环”标志后,将其设置为“ Y”

3 个答案:

答案 0 :(得分:3)

也许在awk中将操作取反。

$ awk -v f1="$1" 'BEGIN             {FS=OFS=","}
                  f1==$1 && $5=="Y" { // do something
                                      $5="N"}1'  file

不确定什么是“做某事”操作,如果您需要调用另一个命令/脚本,也可以。

答案 1 :(得分:1)

使用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
)

我在一个子外壳中运行该命令,以便本地化更改IFS的效果。

这使用sponge写回同一文件。您需要moreutils软件包才能使用它,否则请使用

done < file > tmp && mv tmp file

也许更简单,bash更少

while IFS= read -r line; do
    case $line in 
        "$1",*,Y) 
            # do something
            line="${line%Y}N"
            ;; 
    esac
    echo "$line"
done < file

答案 2 :(得分:0)

将行(,N)结尾的$替换为,Y

sed 's/,N$/,Y/' file