我有一个具有以下特征的文本文件:
我在一些行中添加了一些注释,并提供了对原始单词进行更改的暂时建议,现在我想使用sed为我做出这些更改。所以,为了给出更清晰的图片,我的文件看起来像这样:
NO NO O
SIGNS NN O #NNS
GIVEN VBD B-VP #VBN
AT IN O
THIS NN O
TIME NN O ## B-NP
. PER O
...
1#的注释是替换行中的SECOND字,2#的注释是替换行中的THIRD字。有人能用sed(或awk,或其他任何东西)建议一种方法吗?再次澄清(希望),我的目标是在#或##之后获得模式,并用匹配的模式替换该行的第n个单词。
感谢。
答案 0 :(得分:4)
这对你有用:
awk '/#/{sub(/# +/,"#");n=gsub(/#/,"",$NF);$(n+1)=$NF;$NF="\t\t#"}1' file
/#/{ ... }
:搜索包含#
的行并执行以下步骤... sub(/# +/,"#")
:删除备注与#
之间的所有空格n=gsub(/#/,"",$NF)
:从最后一个字段#
中删除所有$NF
,并将#
的数量设置为变量n
$(n+1)=$NF
:将n + 1字段$(n+1)
设置为新的最后一个字段$NF
,其中#
已被剥离$NF="\t\t#"
:将最后一个字段$NF
设置为两个标签,后跟#
1
:告诉awk
打印更改后的行file
:您的输入文件$ awk '/#/{sub(/# +/,"#");n=gsub(/#/,"",$NF);$(n+1)=$NF;$NF="\t\t#"}1' file
NO NO O
SIGNS NNS O #
GIVEN VBN B-VP #
AT IN O
THIS NN O
TIME NN B-NP #
. PER O
...
注意 :如果您这样做,那么您的笔记始终跟在#
之间,其间的空格为零,则可以移除整个sub(/# +/,"#");
命令的一部分,使其更短
答案 1 :(得分:1)
这可能对您有用:
sed 's/\S*\(\s*\S*\s*#\s*\)\([^#]*\)$/\2\1/;s/ *##*.*/\t\t#/' file
NO NO O
SIGNS NNS O #
GIVEN VBN B-VP #
AT IN O
THIS NN O
TIME NN B-NP #
. PER O
...
答案 2 :(得分:0)
Perl可以处理这个问题。虽然我觉得我更喜欢把它变成一个剧本。
粘贴版本:
perl -lnwe 's/#\K\s+//; my @a=/\S+/g; if (@a>3) { $c = $a[3] =~ tr/#//d; $a[$c] = $a[3]; } print join " ", @a[0..2]' file
此版本将打印到stdout而不更改文件。添加-i.bak
,例如perl -i.bak -lnwe '....'
进行就地编辑,并在file.bak
中进行备份。
可读版本:
$ perl -lnwe ' # -l: handle newlines, -n read file/stdin
s/#\K\s+//; # strip optional spaces
my @a = /\S+/g; # extract the data
if (@a > 3) { # when there are replacements..
my $c = $a[3] =~ tr/#//d; # count and remove #
$a[$c] = $a[3]; # set element number $c to element 3
} print join " ", @a[0..2] # reassemble and print 3 first elements
' file
<强>输出:强>
NO NO O
SIGNS NNS O
GIVEN VBN B-VP
AT IN O
THIS NN O
TIME NN B-NP
. PER O