我有一个简单的问题,似乎找不到合适的解决方案。我有一行有很多这样的行:
2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
我想在第三个字段与954
匹配的所有行中添加前缀1;
,所以它的结果如下:
1;2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
我现在有一个非常糟糕的方法:
cat test.csv | awk -F ';' '{print $1,$2,$3,$4,$5,$6}' | awk '{if($3 == 954) print "1;"$0;}'
但是,当然,输出时使用空格作为分隔符。
如果有人能用更聪明的方法做到这一点,我将不胜感激。非常感谢。
Awk可以轻松完成您的工作
awk 'BEGIN{FS=OFS=";"}$3 == 954{print 1,$0;next}1' file
#OR
awk 'BEGIN{FS=OFS=";"}$3 == 954{$0=1 OFS $0}1' file
#OR
awk 'BEGIN{FS=OFS=";"}{print ($3==954 ? 1 OFS:"") $0}' file
使用您的输入文件:
$ cat file
2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
$ awk 'BEGIN{FS=OFS=";"}$3 == 954{print 1,$0;next}1' file
1;2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
$ awk 'BEGIN{FS=OFS=";"}$3 == 954{$0=1 OFS $0}1' file
1;2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
$ awk 'BEGIN{FS=OFS=";"}{print ($3==954 ? 1 OFS:"") $0}' file
1;2020-10-07;2020-07-17;954;7004;something;something
2020-10-14;2020-07-16;955;10038;something;something
解释
awk 'BEGIN{
FS=OFS=";" # set input and output field separator
}
$3 == 954{ # if 3rd field equal to 954 then
print 1,$0; # print 1 and then existing record/row
next # go to next line
}1
'
$3 == 954{$0=1 OFS $0}1
:如果第三个字段等于954,则修改现有记录/行($0
(,值为1
,输出字段分隔符OFS
,然后输出现有行/记录($0
(。因此,在末尾
}1
:脚本末尾的1是一个没有操作的条件(始终为true(,因此它对每一行执行默认操作,打印该行(可能已被大括号中的前一个操作修改(
这一行也可能有所帮助:
awk -F';' '{p=$3==954?"1;":""}{print p$0}' file
您在输出中丢失;
的原因:
如果您编写print $1,$2...
,awk将使用默认的OFS
,这是一个空格。要解决这个问题,基本上有两种方法:
- 设置
OFS
这很简单,正如另一个答案所示 - 不要设置任何字段,例如不要执行类似
$2=...
的操作,而是使用sub()
、gsub()
来更改文本。打印时,不要包含逗号,
,只需打印连接其他字符串的$0
即可。(我的一句俏皮话是这样说的(
对于sed
,macthing第三列应该可以,但如果它超过5列,那么awk
就是方法。
sed '/([^;]*)([^;]*);954[^;]*(.*)/s/^/1;/' file.txt