我有带有|分隔行的文件,因为我想要添加对第8位置值的检查,如果值匹配,我想从文件中删除该行,如果不匹配,我希望将其保留在文件中。
下面是文件格式,我想删除所有在第8位置有U值的行
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M 我们如何才能做到这个Perl,或者有什么方法,我们可以使用Awk或Sed。但移除后,我也想打印出来。
我试过sed,但是正在匹配我想要匹配的特定位置的文件。
sed -i '' "/$pattern/d" $file发布于 2019-06-13 16:12:01
perl -F'\|' -wlane'print if $F[7] ne "U"' file > new使用-a开关,每一行都被分割成文字,可在@F数组中使用。要拆分的分隔符可以使用-F选项设置(默认为空格),这里是|。见运行中的开关。然后我们检查第八个字段并打印出来。
为了改变输入文件的位置,添加-i开关
perl -i -F'\|' -wlane'print if $F[7] ne "U"' file或者使用-i.bak来保持(.bak)备份。
我看到了一个关于记录没有保存在文件中的行的问题。
一种方法是为他们劫持STDERR流
perl -i -F'\|' -wlane'$F[7] ne "U" ? print : print STDERR $_' file 2> excluded在文件excluded获取STDERR流的地方,使用2>重定向(在bash中)。但是,这完全是危险的,因为现在可能的警告是隐藏的,并且破坏了用于排除行的文件(因为它们也会进入该文件)。
所以最好把这些线条收集起来,在最后打印出来。
perl -i -F'\|' -wlanE'
$F[7] ne "U" ? print : push @exclude, $_;
END { say for @exclude }
' input > excluded其中文件excluded被省略(排除)行。(我把-e换成了-E,这样就有了say。)
发布于 2019-06-13 16:13:24
听起来这可能是你想要的
$ cat file
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
$ awk -i inplace -F'[|]' '$8=="U"{print|"cat>&2"; next} 1' file
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
$ cat file
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M上面的-i inplace使用GNU。对其他的鸟来说,你只需要做:
awk -F'[|]' '$8=="U"{print|"cat>&2"; next} 1' file > tmp && mv tmp file将已删除的行记录到名为log1的文件
awk -F'[|]' '$8=="U"{print >> "log1"; next} 1' file要记录它并将其打印到stderr:
awk -F'[|]' '$8=="U"{print|"tee -a log1 >&2"; next} 1' filehttps://stackoverflow.com/questions/56584382
复制相似问题