【发布时间】:2010-11-06 12:04:31
【问题描述】:
我正在编写一个 shell 脚本,它在某些时候必须获取一个文件,在其中搜索一个特定的单词并删除该单词之后的整个文本(包括单词本身) - awk 是正确的工具我想,但我对其中的编程了解不多。
谁能帮帮我?
【问题讨论】:
我正在编写一个 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,则有各种非标准扩展可以帮助对文件进行原位修改。
【讨论】:
我假设您的输入是这样的:
Lorem ipsum dolor sit amet,
consectetur adipiscing velit。
Nullam neque sapien, molestie vel congue non,
feugiat quistellus。犹他
努拉米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 的两个实例。
您也可以安全地将整个脚本放在一行中。
【讨论】:
awk '/word/{exit}1' file
【讨论】:
我不知道如何用 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.*/, "");打印 } 对于每一行,如果该行包含以 word 开头(以空格开头)并到达行尾的模式 - 用空字符串替换该模式 - 然后打印更新的行。
[ 认为问题可以读取任何一种方式(该行上的整个文本或文件中的整个文本)。如果想跳过文件的其余部分,可以: { skip = gsub(/ word.*/, "");打印 ;如果(跳过)退出}]
【讨论】:
用sed删除部分行,例如:
$ echo '12345 John Smith / red black or blue it is a test' | sed -e 's/\/.*//'
$ 12345 John Smith
【讨论】: