1

我有以下文字:

 FLAGS (\Seen \Flagged))
* 1001 FETCH (BODY[HEADER.FIELDS (message-id subject)] {167}
Message-ID: ail test 13
Subject: =?utf-8?Q?RDM=20Request=20RD00001578:=20Under=20Review=20->=20Requested?=

 FLAGS (\Seen \Flagged))
* 1010 FETCH (BODY[HEADER.FIELDS (message-id subject)] {145}
Subject: RE: ail test 12
Message-ID: <81B1DDBBD5E5D148915DBDF77378184D1036F5CD1B@xxxxxxxxxxxxxxxxxxxxxxxxx>


 FLAGS (\Seen \Flagged))
* 1020 FETCH (BODY[HEADER.FIELDS (message-id subject)] {116}
Subject: RE: ail test 14
Message-ID: <8A20A6EF23B11D41A1B3222195A1B2683AD3D013@xxxxxxxxxxxxxxxxxxxxxxxxx>

我如何使用sedawk获取格式如下:

Subject : the subject
Message-ID: The message ID

我知道如何获取字段,我的主要问题是将所需的顺序放在主题必须始终位于消息 ID 之前的位置。

编辑:

SO 是 ( uname -a ) SunOS serverName 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-15000

4

5 回答 5

2

使用 GNU awk(用于 gensub()):

$ awk -v RS= '{
    print gensub(/.*\n(Subject[^\n]+).*/,"\\1","")
    print gensub(/.*\n(Message[^\n]+).*/,"\\1","")
}' file
Subject: =?utf-8?Q?RDM=20Request=20RD00001578:=20Under=20Review=20->=20Requested?=
Message-ID: ail test 13
Subject: RE: ail test 12
Message-ID: <81B1DDBBD5E5D148915DBDF77378184D1036F5CD1B@xxxxxxxxxxxxxxxxxxxxxxxxx>
Subject: RE: ail test 14
Message-ID: <8A20A6EF23B11D41A1B3222195A1B2683AD3D013@xxxxxxxxxxxxxxxxxxxxxxxxx>

您可以在任何 awk 中使用 match()+substr() 或几个 sub() 代替 gensub() 来执行相同的操作。

于 2013-03-14T13:52:57.207 回答
1

按顺序打印值:

$ awk '/^Subject:/{s=$0}/^Message-ID:/{m=$0}s&&m{print s"\n"m"\n";s=0;m=0}' file
Subject: =?utf-8?Q?RDM=20Request=20RD00001578:=20Under=20Review=20->=20Request...
Message-ID: ail test 13

Subject: RE: ail test 12
Message-ID: <81B1DDBBD5E5D148915DBDF77378184D1036F5CD1B@xxxxxxxxxxxxxxxxxxxxxx...

Subject: RE: ail test 14
Message-ID: <8A20A6EF23B11D41A1B3222195A1B2683AD3D013@xxxxxxxxxxxxxxxxxxxxxxxxx>
于 2013-03-14T13:32:52.923 回答
1

段落模式 ( ) 中使用-00

perl -00 -lne '
    ($subject) = $_ =~ m/Subject:\s*(.*)/;
    ($message) = $_ =~ m/Message-ID:\s*(.*)/;
    print "Subject: $subject\nMessage-ID: $message"
' input.txt

输出

Subject: =?utf-8?Q?RDM=20Request=20RD00001578:=20Under=20Review=20->=20Requested?=
Message-ID: ail test 13

Subject: RE: ail test 12
Message-ID: <81B1DDBBD5E5D148915DBDF77378184D1036F5CD1B@xxxxxxxxxxxxxxxxxxxxxxxxx>

Subject: RE: ail test 14
Message-ID: <8A20A6EF23B11D41A1B3222195A1B2683AD3D013@xxxxxxxxxxxxxxxxxxxxxxxxx>

笔记

来自perldoc perlrun

-0[八进制/十六进制]

将输入记录分隔符 ($/) 指定为八进制或十六进制数。
特殊值 00 将导致 Perl 以段落模式 slurp 文件。任何 0400 或更高的值都会导致 Perl 读取整个文件,但按照惯例,值 0777 是通常用于此目的的值。

于 2013-03-14T13:36:01.953 回答
0

如果您允许自己多次阅读文件sed,则无需:awk

grep '^Subject:' your_file | paste -d "\n" - <(grep '^Message-ID' your_file)

如果您想要记录之间的空行:

grep '^Subject:' your_file | paste -d "\n" - <(grep '^Message-ID' your_file) | sed -e '3,$s/^Subject:/\n&/'

请注意,如果文件在读取时可以更改,则此方法不起作用。

于 2013-03-14T14:53:58.633 回答
0

sed中,这有点棘手:

sed -n -e '/^Subject:/H;/^Message-ID:/H' \
    -e 'x' \
    -e '/\nSubject:.*\n.*/{s/^\n//;p;s/.*//}' \
    -e '/\nMessage-ID:.*\n.*/{s/^\n\(.*\)\n\(.*\)/\2\n\1/;p;s/.*//}' \
    -e 'x' \
    your_file

该脚本的思想如下:

  1. Subject:将以of开头的行存储Message-ID:在保持空间 (1st -e) 中。
  2. 为每一行做#1,在读取一条记录后,我们将有\nSubject:.*\n.*\nMessage-ID:.*\n.*在保持空间中。
  3. 然后工作保持空间很容易获得预期的输出。
于 2013-03-14T15:09:48.793 回答