我有以下文件格式
Received from +11231231234 at 2021-10-10T19:56:50-07:00:
This is a message that contains words like from, at, etc.
Sent to +11231231234 at 2021-10-11T06:50:57+00:00:
This is another message that contains words like to, at, etc.
我想清理“已接收”和“已发送”行,以下 sed 命令可实现此目的
cat file | sed 's/from//g' | sed 's/to/ /g' | sed 's/+\w\+//' | \
sed 's/at//g' | sed 's/T/ /g' | sed 's/[[:digit:].]*\:$//' | \
sed 's/[[:digit:].]*\:$//' | sed 's/-$//' | sed 's/-$//' | sed 's/+$//'
并产生以下结果
Received 2021-10-10 19:56:50
This is a message that contains words like , , etc.
Sent 2021-10-11 06:50:57
This is another message that contains words like , , etc.
如您所见,它确实很好地清理了“已接收”和“已发送”行。但它也清理了消息行!我怎样才能仅在以“已接收”和“已发送”开头的行上应用这些操作?
答案1
您可以使用模式来挑选要应用后续命令的行:
sed '/^Sent\|^Received/ s/pattern/replacement/' your_file
奖金
实际上,您只需一个 sed 命令即可完成所有编辑:
sed '/^Received\|^Sent/ s/\(^[^ ]*\).*at \(.*\)T\(.*\)[-+].*/\1 \2 \3/' your_file
本质上,模式匹配行上的每一段文本,我们只需“记住”所有我们想要保留的位,然后用它们替换整行。
输出:
Received 2021-10-10 19:56:50
This is a message that contains words like from, at, etc.
Sent 2021-10-11 06:50:57
This is another message that contains words like to, at, etc.
其工作方式如下:
\(
和\)
是“捕获组”,可以记住它们之间匹配的所有内容。^[^ ]*
匹配一行的开头,后跟任意数量的连续非空白字符(即该行的第一个单词)。.*at
匹配所有内容,包括单词“at”(以及其后的空格) - 这不在捕获组中,因此不会被“记住”。\(.*\)T
记住(在第二个捕获组中)所有内容,但不包括大写字母“T”。\(.*\)[-+].*
记住(在第三个捕获组中)所有内容,但不包括“-”或“+”(以及“-/+”后面的任何内容)。/\1 \2 \3/
表示用第 1、第 2 和第 3 个捕获组的内容替换匹配项(即整行)。
这一页很好地解释了 sed - 它还有一套很棒的其他 unix 教程。