我在这里找到了一个问题的答案:"sed" command to remove a line that match an exact string on first word
...但只是部分原因,因为该解决方案仅在我查询的答案与答案人员完全一致时才有效。
他们回答说:
sed -i "/^maria\b/Id" file.txt
...只删除以“maria”开头的一行,而不是maria,如果它不是第一个单词的话。
我想在一个文件中删除一个特定的URL,例如:“cnn.com” - 但是,我还有一堆本地主机地址,0.0.0.0,并且两者都有一些前面有一个空格。我也不想删除像ads.cnn.com这样的子域名,这样代码“应该”可以工作,但是当我使用-e选项输入更多命令时,代码“不应该”。我的下面的代码似乎清理得很好,除了我不能让它击败cnn.com!我的文件名为raw.txt
sed -r -e 's/^127.0.0.1//' -e 's/^ 127.0.0.1//' -e 's/^0.0.0.0//' -e 's/^ 0.0.0.0//' -e '/#/d' -e '/^cnn.com\b/d' -e '/::/d' raw.txt | sort | tr -d "[:blank:]" | awk '!seen[$0]++' | grep cnn.com
当我grep for cnn.com时,我看到所有的cnn包括我不想要的那个实际上是“cnn.com”。
ads.cnn.com
cl.cnn.com
cnn.com <-- the one I don't want
cnn.dyn.cnn.com
customad.cnn.com
gdyn.cnn.com
jfcnn.com
kermit.macnn.com
metrics.cnn.com
projectcnn.com
smetrics.cnn.com
tiads.sportsillustrated.cnn.com
trumpincnn.com
victory.cnn.com
xcnn.com
如果我只是使用cnn.com中的一段代码,它似乎有效。
sed -r '/^cnn.com\b/d' raw.txt | grep cnn.com
* I'm not using the "-e" option
结果:
ads.cnn.com
cl.cnn.com
cnn.dyn.cnn.com
customad.cnn.com
gdyn.cnn.com
jfcnn.com
kermit.macnn.com
metrics.cnn.com
projectcnn.com
smetrics.cnn.com
tiads.sportsillustrated.cnn.com
trumpincnn.com
victory.cnn.com
xcnn.com
当我将命令与“-e”选项一起使用时,我所做的任何事情似乎都无效。我需要一些帮助才能让我的多选项命令与SED一起踢。
有什么建议吗?
Ubuntu 12 LTS&amp; 16 LTS。
sed(GNU sed)4.2.2
答案 0 :(得分:0)
.
是正则表达式中的元字符,表示&#34;匹配任何一个字符&#34;。因此,您不小心创建了一个也会捕获cnnPcom
或cnn com
或cnn\com
的正则表达式。虽然它可能适合您的需求,但最好更明确一点:
sed -r '/^cnn\.com\b/d' raw.txt
这里的区别是\
期之前的.
反斜杠。这逃脱了时期元素,因此它被视为一个字面时期。
对于以空格开头的行,您可以在单个正则表达式中捕获这些行(再次转义句点元字符):
sed -r '/(^[ ]*|^)127\.0\.0\.1\b/d' raw.txt
此(^[ ]*|^)
表示以任意数量的重复空格^[ ]*
或|
开头的行以^
开头,然后是127.0.0.1
的匹配}。
然后,为了将这些字符串串在一起,您可以使用parantheses中的|
OR运算符来捕获所有匹配项:
sed -r '/(^[ ]*|^)(127\.0\.0\.1|cnn\.com|0\.0\.0\.0)\b/d' raw.txt
或者,您可以使用;
分号来分隔不同的正则表达式:
sed -r '/(^[ ]*|^)127\.0\.0\.1\b/d; /(^[ ]*|^)cnn\.com\b/d; /(^[ ]*|^)0\.0\.0\.0\b/d;' raw.txt
答案 1 :(得分:0)
sed不理解字符串上的匹配,只理解正则表达式,并且尝试让sed像它一样行动是非常困难的,请参阅Is it possible to escape regex metacharacters reliably with sed。删除第一个以空格分隔的单词为“foo”的行只是:
awk '$1 != "foo"' file
删除以“foo”或“bar”开头的行只是:
awk '($1 != "foo") && ($1 != "bar")' file
如果您只有几个单词,那么方法是将它们全部列出并创建一个由它们索引的哈希表,然后测试您的行的第一个单词是哈希表的索引:
awk 'BEGIN{split("foo bar other word",badWords)} !($1 in badWords)' file
如果那不是您想要的,那么请编辑您的问题以阐明您的要求,并提供简洁,可测试的样本输入和 预期输出。