仅对以特定字符串开头的行应用 sed 操作

仅对以特定字符串开头的行应用 sed 操作

我有以下文件格式

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 教程

相关内容