我有一个文件 .txt ,里面有
ID VALUE
test value_1
testing value_2
first value_3
second value_4
我正在尝试编写一个 shell 脚本,它将删除与给定 ID 对应的行。例如,我想删除 ID 为“test”的行,因此我在论坛上找到了可以通过以下方式使用“sed”函数的方法:
sed -i '/test/d' file.txt
但是,此函数也会删除 ID 为“testing”的行,因为该单词与单词“test”合成。此外,该函数将检查每一行,因此如果存在带有“test”单词的值,它也会被删除。
所以,
- 如何检查和删除 ID 列中仅包含“test”一词的每一行,鉴于 ID 位于每行的开头,我还可以问如何检查和删除以“test”一词开始的每一行?
- 如何仅当ID为“test”且不与单词“test”复合时删除(在本例中,“testing”为delete)
- “sed”功能真的足够吗?
谢谢
答案1
使用\b
或\s
和^
\b
匹配单词边界,并^
匹配行的开头:
sed -i '/^test\b/d' file.txt
\b
如果您的列以空格分隔,请考虑\s
匹配空格字符,而不是。
是否sed
足够?
是的。
以下是命令行文本处理中(大多数)其他“常见嫌疑人”的简要提及:
或者,有时我会grep
用于类似的目的,特别是如果我只是想处理文件的副本、重定向输出或将输出流式传输到另一个实用程序:
grep -v '^test\b' file.txt
或使用-w
单词匹配:
grep -vw '^test' file.txt
两者输出:
ID VALUE
testing value_2
first value_3
second value_4
一旦您进入高级脚本语言,还有许多其他更强大的选项可用。awk
是一个很好的中间选择,并且擅长处理表格输入,如下所示:
awk 'NR > 1 && $1 != "test" { print $1,":",$2 }' test.txt
NR > 1
跳过第一行(标题行),并$1 != "test"
使用简单的字符串比较而不是正则表达式(尽管您可以等效地使用!/^test /
)。该{ print ... }
块打印出由冒号分隔的第一列和第二列(任意,只是为了向您展示一些可能的内容):
testing : value_2
first : value_3
second : value_4
所以awk
是一个很好的学习工具。之后,您就进入了完整的编程语言领域,如 Perl、Python 等。它们可用于单行程序或庞大的软件套件。
答案2
@type_outcast
谢谢你的回答。我找到了一个解决方案,这就是为什么我选择自己问题的答案:我在论坛上找到了如何删除以给定单词开头的每个人
sed '/^test/ d'
所以我使用以下行“加入”它
sed -i '/^test\b/d' file.txt
最终看起来像
sed /^\btest\b/ d
最后一个命令行将允许您删除以单词边界“test”开头的每一行