我试图注释掉除第一个之外的所有其他事件。
原始样本.txt
一 二 三 二 二 #二
样本.txt
一 二 三 #二 ##二 #二
我只能注释掉所有发生的事情。使用:
sed -i /两个/s/^/#/
但这也注释掉了已经注释的事件。这也注释掉了发现该事件的行。我该如何解决这个问题?我正在 ubuntu 基线映像上测试这个,所以我不能特别安装任何东西。
答案1
至少使用 GNU sed(Ubuntu 上默认应该有)你可以执行诸如0,/pattern/
.所以也许是这样的:
$ sed '0,/^two/!s//#&/' original.txt
one
two
three
#two
#two
#two
这表示“对于除了第 0 行和第一个匹配项之间的每一行/^two/
,替换为,后跟您刚刚匹配的内容。替换中的空模式与前面的正则表达式匹配,并且/^two/
替换刚刚匹配的内容 - 一个非高尔夫版本将会#
//
&
sed '0,/^two/!s/^two/#two/' original.txt
由于^two
锚定到行的开头,因此它与已注释的事件不匹配 - 如果是不是你想要什么,删除^
.
答案2
perl -p -i -e '$_ = ("#" x $count{$_}++) . $_' your-file
产生您的预期结果。它为每行添加与#
之前出现过的相同行一样多的前缀。
上面的选项-i
编辑文件我n-place(实际上-i
在某些sed
实现中找到的选项显然是从 复制的perl
)。
答案3
sed
众所周知,他不善于计算。使用以下方法更容易awk
:
$ awk '/^two/ { if (++count > 1) $0 = "#" $0 }; 1' file
one
two
three
#two
#two
#two
在首先看到被忽略的此类行之后,这会#
在以字符串开头的每一行前面添加一个字符。然后,无论是否修改,所有行都会被打印(通过代码中的two
尾部,可以用 替换)。1
{ print }
答案4
这并不完全是您想要的,但如果我理解正确的话,您希望最终得到一个文件,其中未注释的条目是唯一的,其他所有内容都已注释。我不知道你将如何做到这一点,但一种解决方法是保持原始文件完好无损,并最终得到另一个具有唯一文件的文件......
$ cat sample.txt | uniq | grep -v ^#
one
three
two