1

恐怕我不是列出的三个工具中的任何一个的专家,所以我问你们所有人。

我有一个大文本文件,可以分成多个部分,每个部分都有页眉ABC和页脚&&。典型的文件如下所示:

ABC

...

<ID>
123

...

&&

ABC

...

<ID>
124

...

&&

我需要根据给定的 检索一个部分ID,例如,如果ID=123,我希望输出为:

ABC

<ID>
123

&&

ABC <ID>在和 之间123和之间有随机数据的地方&&。实际的ID, 123, 是可变的。

我相信awk '/ABC/,/\&\&/'在找到每个小节时做的工作,但我不知道如何获得与正确 ID 对应的小节。提前感谢您的帮助。

编辑:澄清了问题和示例输入。

4

4 回答 4

1

此解决方案假定您的输入文件仅由ABC ... <ID> ... &&部分组成,可能由空行分隔。

用法: awk -f foo.awk ID=123 input_file

foo.awk:

#!/usr/bin/awk -f
BEGIN {
    RS = "\n&&\n";
    ORS = RS;
}

match($0, "<ID>\n" ID "\n") {
    sub(/^\n/,"",$0);
    print $0;
}

如果/usr/bin/awk匹配您的 awk 并且您使 foo.awk 可执行,您可以直接调用它:./foo.awk ID=123 input_file

此代码将您的输入拆分&&为单行上的每个记录。
然后它搜索记录

<ID>
your_id

如果找到匹配项,则打印它。

sub(/^\n/,"",$0);只是消除了部分之间的空白行。

您也可以将其放在一行中:

 awk 'BEGIN{ID=124;RS="\n&&\n";ORS=RS};match($0, "<ID>\n" ID "\n") {sub(/^\n/,"",$0);print $0;}' input_file
于 2012-07-25T19:46:57.213 回答
0

在 sed 中,您可以这样做:

sed -i ' /ABC/,/&&/ !{d} ' FILE

这将保留 ABC 和 && 之间的所有上下文。

于 2012-07-25T18:31:53.487 回答
0

用法:awk -v id=123 -f foo.awk foo.txt

foo.awk

$0=="ABC",$0=="&&"{
    # store everything in data
    # ternary operation to avoid leading "\n"
    data=data?(data "\n" $0):$0
}


id_flag {
    # this is a string after "<ID>"
    if (id==$1) { 
       print_flag = 1
    }
    id_flag = 0
}

$0=="<ID>"{
    # prepare to read id
    id_flag = 1
}

$0=="&&"{
    if (print_flag) {
      print data
      print_flag = 0
    }
    data = ""
}
于 2012-07-25T18:45:48.643 回答
0

这可能对您有用(GNU sed):

id=123
sed '/^ABC/,/^&&/{/^ABC/{h;d};H;/^&&/!d;g;/<ID>\n'"$id"'/p};d' file

另一种方法:

sed ':a;$bb;N;/^ABC/!D;/&&$/!ba;:b;/^ABC.*<ID>\n'"$id"'.*&&$/p;d' file
于 2012-07-25T20:10:44.527 回答