0

我有一个由逗号分隔的 4 列的文本文件。当我在循环中读取每条记录时,我想根据条件向第 5 列添加一个值。因此,如果我知道行号和列号,如何在不使用临时文件的情况下使用 awk/sed 命令替换/设置该特定字段的值?我想(直接)更新我正在读取的文件

inp.txt
a,b,c,d
e,f,g,h
i,j,k,l

谢谢,-sri

4

4 回答 4

2

您不能使用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 略少。

于 2012-12-12T01:24:30.717 回答
2

我不能代表 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,
于 2012-12-12T01:26:23.337 回答
1
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
于 2012-12-12T06:19:25.750 回答
0

你的意思是这样吗?这是不使用任何临时文件的版本。

[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

干杯,

于 2012-12-12T01:34:43.273 回答