我有一个由逗号分隔的 4 列的文本文件。当我在循环中读取每条记录时,我想根据条件向第 5 列添加一个值。因此,如果我知道行号和列号,如何在不使用临时文件的情况下使用 awk/sed 命令替换/设置该特定字段的值?我想(直接)更新我正在读取的文件
inp.txt
a,b,c,d
e,f,g,h
i,j,k,l
谢谢,-sri
您不能使用awk
或直接编辑文件sed
。某些版本sed
的选项 ( -i
) 可以处理临时文件并覆盖原始文件,但实际上并没有就地编辑文件。这没什么大不了的。做就是了:
$ awk 'NR==5{ $(NF+1) = "new value"}1' OFS=, FS=, input-file > tmp.$$
$ mv tmp.$$ input-file
将新列添加到 的第 5 行input-file
。如果您愿意,可以使用ed
来编辑文件,但使用临时文件更有意义。如果你想假装你没有使用临时文件,并且你的 sed 支持-i
,你可以做同样的事情:
sed -i '5s/$/,new value/' input-file
尽管大多数实用程序不允许对文件进行就地修改,但使用以下sh
函数之一使用临时文件来模拟该行为很简单:
edit() { local f=$1; shift; "$@" < $f > $f.$$ && mv $f.$$ $f; } # Break hard links
edit() { local f=$1; shift; "$@" < $f > $f.$$ && cat $f.$$ > $f && rm $f.$$; }
使用其中任何一个,您都可以awk
使用edit filename awk awk-cmds
. 第一个版本中断了硬链接,但使用的 IO 略少。
我不能代表 sed,但 awk 的目的不是编辑文件,而是写入标准输出。
但无论如何,这是一个不需要循环的解决方案,假设条件是第 4 列中的条目是 h。
awk -F ',' '{ if ($4 == "h") print $0",z"; else print $0","}' inp.txt > out.txt
输出:
a,b,c,d,
e,f,g,h,z
i,j,k,l,
perl -i -F, -lane 'if($.==<row number>){$F[<column_number>-1]+=<add your stuff here>}print join(",",@F)' your_file
测试如下:
>cat temp
b,c,d,g
r,g,d,s
执行以更改第二行中的第三列:
>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
> cat temp
b,c,d,g
r,g,10,s
你的意思是这样吗?这是不使用任何临时文件的版本。
[a@b ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,\2,\3,\4_g'
inp.txt
a,b,c,d
e,f,g,h
i,j,k,l
[a@b ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,sth,\3,\4_g'
inp.txt
a,sth,c,d
e,sth,g,h
i,sth,k,l
[a@b ~]$ sed -ie 's_^\(.*\),\(.*\),\(.*\),\(.*\)_\1,sth,\3,\4_g' tmp
[a@b ~]$ cat tmp
inp.txt
a,sth,c,d
e,sth,g,h
i,sth,k,l
干杯,