使用gsub更改列的值

时间:2019-03-06 19:36:26

标签: unix awk

我必须使用unix命令更改文件第一列的所有值(标题除外)。

我尝试以下操作,但似乎正在删除文件中的所有内容:

awk -F\| -v val="20190306" '{gsub($1,val); print}' file > file

此外,20190306通常是一个变量,我用一个值的示例代替。我希望能够将此变量设置为日期格式,例如2019-03-06而不是20190306

我的输入是:

Value_date; CPTY 2018-10-17;INVEST 2018-10-17;USD

我想要的输出是:

Value_date; CPTY 2019-03-06;INVEST 2019-03-06;USD

我的awk版本是:3.1.7

2 个答案:

答案 0 :(得分:2)

awk -F\| -v val="20190306" '{gsub($1,val); print}' file > file
# ......................................................^^^^^^

之前,您的文件被截断为零长度,甚至开始执行awk命令。然后,shell 首先处理重定向。

您需要输出到一个临时文件,然后将temp文件移到原始的如果 awk命令成功完成:

tmp=$(mktemp)
awk ... file > "$tmp" && mv "$tmp" file

您还可以使用其他技术:

  • 先安装moreutils软件包,然后再安装awk ... file | sponge file

答案 1 :(得分:0)

您用自己的代码误导了我们,没有示例输入和输出...
根据您输入的内容以及您在评论中显示的内容,我相信使用sed会更好:

val='20190306'
sed -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/'"${val:0:4}-${val:4:2}-${val:6:2}"'/g' file

或者在这种情况下,也可以这样做:

sed -e "s/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/${val:0:4}-${val:4:2}-${val:6:2}/g" file

当输出看起来不错时,添加-i开关(sed -i -e ...)来更改文件。

如果要使用awk:

awk -v newd="${val:0:4}-${val:4:2}-${val:6:2}" '{gsub(/[0-9]{4}(-[0-9]{2}){2}/, newd);}1' file

但是由于您没有GNU awk v4.1.0+,因此无法使用-i inplace进行位置更改。
您可以尝试:

awk -v newd="${val:0:4}-${val:4:2}-${val:6:2}" '{gsub(/[0-9]{4}(-[0-9]{2}){2}/, newd);}1' file | tee file

如果它不起作用,则必须使用临时文件,如下所示:

awk -v newd="${val:0:4}-${val:4:2}-${val:6:2}" '{gsub(/[0-9]{4}(-[0-9]{2}){2}/, newd);}1' file > temp_file
mv -f temp_file file