我有一个由逗号分隔的4列的文本文件。 当我在循环中读取每个记录时,我想根据条件向第5列添加值。 因此,如果我知道行号和列号,如何在不使用临时文件的情况下使用awk / sed命令替换/设置该特定字段的值? 我想直接更新我正在阅读的文件
inp.txt
a,b,c,d
e,f,g,h
i,j,k,l
谢谢, -SRI
答案 0 :(得分:2)
您无法使用awk
或sed
直接编辑文件。某些版本的sed
有一个选项(-i
),可以使用临时文件并覆盖原始文件,但实际上并不会编辑该文件。这不是什么大问题。只是做:
$ awk 'NR==5{ $(NF+1) = "new value"}1' OFS=, FS=, input-file > tmp.$$
$ mv tmp.$$ input-file
在input-file
的第5行添加新列。如果您愿意,可以使用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略少。
答案 1 :(得分:2)
我不能说sed,但awk的目的不是编辑文件而是写入stdout。
但无论如何,这是一个你不需要循环的解决方案,假装条件是第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,
答案 2 :(得分: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
执行更改第二行中的第3列:
>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
> cat temp
b,c,d,g
r,g,10,s
答案 3 :(得分: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
干杯,