unix sed,替换同一文件中特定行和列的字段

unix sed,替换同一文件中特定行和列的字段,sed,awk,Sed,Awk,我有一个文本文件,其中有4列由逗号分隔。 当我在循环中读取每条记录时,我想根据条件向第5列添加一个值。 因此,如果我知道行号和列号,我如何使用awk/sed命令替换/设置该特定字段的值而不使用临时文件? 我想(直接)更新我正在读取的文件 inp.txt a,b,c,d e,f,g,h i,j,k,l 谢谢, -sri您不能使用awk或sed直接编辑文件。某些版本的sed具有一个选项(-i),该选项可与临时文件一起使用并覆盖原始文件,但实际上并不在位编辑文件。这没什么大不了的。只要做: $ aw

我有一个文本文件,其中有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行
。如果愿意,可以使用
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.$$; }
edit(){local f=$1;shift;“$@”<$f>$f.$$&&mv$f.$$$f;}断开硬链接
edit(){local f=$1;shift;“$@”<$f>$f.$$&&cat$f.$$>$f&&rm$f.$$;}

使用这两种方法中的任何一种,您都可以使用
awk
提供使用
edit filename awk-awk cmds在适当位置编辑文件的外观。第一个版本断开硬链接,但使用的IO稍少。

您不能使用
awk
sed
直接编辑文件。某些版本的
sed
具有一个选项(
-i
),该选项可与临时文件一起使用并覆盖原始文件,但实际上并不在位编辑文件。这没什么大不了的。只要做:

$ awk 'NR==5{ $(NF+1) = "new value"}1' OFS=, FS=, input-file > tmp.$$
$ mv tmp.$$ 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.$$; }
edit(){local f=$1;shift;“$@”<$f>$f.$$&&mv$f.$$$f;}断开硬链接
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,

我不能代表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,
你是说像这样? 这是不使用任何临时文件的版本

[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
干杯,

你是说像这样?
perl -i -F, -lane 'if($.==<row number>){$F[<column_number>-1]+=<add your stuff here>}print join(",",@F)' your_file
这是不使用任何临时文件的版本

[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
干杯

perl -i -F, -lane 'if($.==<row number>){$F[<column_number>-1]+=<add your stuff here>}print join(",",@F)' your_file
执行以更改第二行的第三列:

>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
> cat temp
b,c,d,g
r,g,10,s
执行以更改第二行的第三列:

>perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
> cat temp
b,c,d,g
r,g,10,s

它正在使用一个临时文件。检查您的sed文档。它正在使用临时文件。检查您的sed文档。上面可以更简洁地写为:
awk-F',“{print$0fs($4==“h”?“z”:“)}”inp.txt>out.txt
上面可以更简洁地写为:
awk-F',“{print$0fs($4==“h”?“z”:“)}”inp.txt>out.txt