我正在编写一个 shell 脚本,它在某些时候必须获取一个文件,在其中搜索一个特定的单词并删除这个单词之后的整个文本(包括单词本身) - 我想 awk 是正确的工具,但我对其中的编程知之甚少。
有人可以帮我吗?
我想“awk”是这项工作的一个工具,尽管我认为“sed”对于这个特定的操作来说更简单。规范有点模糊。简单的版本是:
为此,我会使用“sed”:
sed '/word/,$d' file
更复杂的版本是:
我可能仍然使用'sed':
sed -n '1,/word/{s/word.*//;p}' file
这颠倒了逻辑。默认情况下它不打印任何内容,但是对于第 1 行,直到包含单词的第一行它会执行替换(直到包含单词的行之前什么都不做),然后打印。
可以在“awk”中完成吗?并非完全微不足道,因为 'awk' 将输入行自动拆分为单词,并且您必须使用函数来进行替换。
awk '/word/ { if (found == 0) {
# First line with word
sub("word.*", "")
print $0;
found = 1
}
}
{ if (found == 0) print $0; }' file
(已编辑:将 'delete' 更改为 'found',因为 'delete' 是 'awk' 中的保留字。)
在所有这些示例中,输入文件的截断版本被写入标准输出。要就地修改文件,您需要使用 Perl 或 Python 或类似语言,或者将输出捕获到临时文件中,一旦命令完成,您将复制原始文件。(如果您尝试“脚本文件”,您将处理一个空文件。)
有多种早期退出优化可以应用于 sed 和 awk 脚本,例如:
sed '/word/q' file
而且,如果您假设使用 GNU 版本的 awk 或 sed,则有各种非标准扩展可以帮助就地修改文件。
awk '/word/{exit}1' file
我假设您的输入是这样的:
Lorem ipsum dolor sit amet,
consectetur adipiscing velit。
Nullam neque sapien,molestie vel congue non,
feugiat quis tellus。Ut quis
nulla mi。Maecenas 舌叶。
并且您希望输出在这样的单词处被切断'vel'
:
Lorem ipsum dolor sit amet,
consectetur adipiscing velit。
Nullam neque sapien, molestie
在这种情况下,您的 awk 脚本将是:
cat lorem.txt | awk '
/\<vel\>/
{
print substr($0, 0, match($0, /\<vel\>/) - 1);
exit;
}
{ print }
'
您要截断的单词需要替换vel
脚本中单词的两个实例。
您也可以安全地将整个脚本放在一行中。
用 sed 删除部分行,例如:
$ echo '12345 John Smith / red black or blue it is a test' | sed -e 's/\/.*//'
$ 12345 John Smith
我不知道如何用 awk 来做,但你可以用 sed 来做:
sed -i~ -e 's/the-word-to-find.*$//' the-file
这将删除从the-word-to-find
行尾到包含the-word-to-find
. 如果您想在第一次出现 时删除文件的其余部分the-word-to-find
,您可以执行以下操作:
sed -i~ -e 's/\(the-word-to-find\).*$/\1/;/the-word-to-find/,$d'
这个 awk 单行代码应该可以解决问题:{ sub(/ word.*/, ""); print } 对于每一行,如果该行包含以 word 开头(以空格开头)并到达行尾的模式 - 用空字符串替换模式 - 然后打印更新的行。
[ 认为问题可以读取任何一种方式(该行上的整个文本或文件中的整个文本)。如果想跳过文件的其余部分,可以: { skip = gsub(/ word.*/, ""); 打印 ; 如果(跳过)退出}]