【问题标题】:How to extract data from strings in file in this case, in linux?在这种情况下,如何在 linux 中从文件中的字符串中提取数据?
【发布时间】:2013-12-05 10:19:21
【问题描述】:

我有一个文件,其行如下所示:

   IBACS6XX P24 ( .PADM(TEST_3), .QC(P1_87P_Z_3) );
   OBAXXCSXX08 P77 ( .A(P1_158P_N1_PROBE_SEL), .PADM(N1_SELECT) );
   inv0_p U99 ( .A(P1_P1_2P_P1_P1_19P_Z_0), .Q(n00) );
   IBACS6XX P25 ( .PADM(TBUSREQN), .QC(tbusreqn) );
   IBACS6XX P26 ( .PADM(NX_N2N), .QC(P1_177P_Z_0) );
   OBAXXCSXX08 P27 ( .A(P1_158P_N2G6PC), .PADM(N2G6PCC) );
   OBAXXCSXX08 P28 ( .A(P1_158P_N1G6PC), .PADM(N1G6PCC) );
   IOACS3P6CSXE04 P46 ( .A(P1_158P_DOUT_7), .EN(FE_OFN21_P1_158P_DATA_OUTN), 
      .PADM(DATA_7), .MA(LTIEHI_5_NET), .MB(P1_87P_Z_0_INV), .QC(P1_49P_ZI_7) );
   IOACS3P6CSXE04 P47 ( .A(P1_158P_DOUT_6), .EN(FE_OFN21_P1_158P_DATA_OUTN), 
      .PADM(DATA_6), .MA(LTIEHI_5_NET), .MB(P1_87P_Z_0_INV), .QC(P1_49P_ZI_6) );

现在问题来了,我希望提取 3 项数据并将它们放入一个以空格字符分隔的新文件中

(1) 第一项,例如第一行的IBACS3XX

(2) 第二项以 P 开头,后跟 2 位数字,通常为 3 个字符长。在第二项之后,我们总是得到一个左括号。例如第一行的 P24

(3) 和 .PADM( 和右括号 ) 之间的项目,例如第一行中的 TEST_3

如何在 Linux 中做到这一点?你有更好的方法吗?

问题是:

(1) 某些行被分成两行,因此 .PADM( 可能会出现在第二行而不是最后两个示例中。

(2) .PADM( 并不总是出现在行中的同一位置,如第二个示例所示。

(3) 所有行都不感兴趣,只有那些以 IBA OBA 或 IOA 开头的行,如上所示。如果一行不以这些字符开头,则可以忽略它。这是网表文件的一部分。

所有行都用';'“关闭”符号,否则它们继续到文本文件的下一行。

我假设 awk 和 sed 可以组合使用,但不确定如何使用。

编辑:

它工作得很好,现在一小步就是从网表中过滤掉这些:

 ggppxbp P74 (  );
 ggppxbp P74VDD (  );
 ggppxbg P75 (  );
 ggppxbg P75VSS (  );

我只想丢弃最后一个括号和分号。这些单元格总是以 ggppxb 开头,最后一个字母表示是 5v 还是 GND 连接,因此只有最后一个字母会改变。

我认为我可以将 ggppxbp 放入 || 之后的 if 语句中象征。但是,如何丢弃括号和分号,并将剩余两项包含到输出文件中?

【问题讨论】:

    标签: linux sed awk pattern-matching text-extraction


    【解决方案1】:

    试试这个 awk 程序。它假定最多有一个延续线,但如果需要,可以通过将第一个 if 替换为 while 我猜想来更改以处理更多。

    {
        if (! /;/ ) {
            L=$0
            getline
            $0=L $0
        }
        if ($1 ~ /^IBA/ || $1 ~ /^OBA/ || $1 ~ /^IOA/) {
            A=$1
            B=$2
            gsub(".*PADM\\(","")
            gsub("\\).*","")
            print A,B,$0
        }
    }
    

    要处理其他项目,请尝试:

    {
        if (! /;/ ) {
            L=$0
            getline
            $0=L $0
        }
        print NR,$0
        if ($1 ~ /^IBA/ || $1 ~ /^OBA/ || $1 ~ /^IOA/ || $1 ~ /^ggppxb/ ) {
            A=$1
            B=$2
            gsub(".*PADM\\(","")
            gsub("\\).*","")
            gsub("\\(.*","")
            print A,B,$0
        }
    }
    

    如果您想了解有关 awk 的更多信息,请阅读精彩的书籍 Gawk: Effective AWK Programming

    【讨论】:

    • 如何在控制台窗口中运行它,我应该复制并粘贴它吗?我在哪里放置输出文件名?我应该把输入文件名放在哪里?
    • 将程序保存为x.awk,然后运行awk -f x.awk < infile > outfile
    • 哇!我希望我能以某种方式奖励你,它工作得很好。唯一的问题是在第 2 项和第 3 项之间有许多空格字符的几行,但可以通过在记事本等文本编辑器中使用“替换”来解决。还有一件事。假设我也希望包括这些 ggppxbp P74 ( ); ggppxbp P74VDD ( ); ggppxbg P75 ( ); ggppxbg P75VSS ( );我该怎么做呢?最后一个小括号和分号需要被丢弃。我真的是第一次使用linux脚本。
    • 实际上这些项目是在单独的行中,我已经通过编辑修改了原始问题。我也在阅读你发给我的链接。谢谢。
    • @quantum231 如果它对您有用,请考虑 accepting the answer。您可能还想参考this
    【解决方案2】:
    sed -n '
    /^[[:blank:]]*OBA[A-Z0-9]\{5\}/ b treat
    /^[[:blank:]]*IBA[A-Z0-9]\{5\}/ b treat
    /^[[:blank:]]*IOA[A-Z0-9]\{5\}/ b treat
    b
    
    : treat
       {
       s/[^;][[:blank:]]*$/&/
       t full
       N
    : full
       s/^[[:blank:]]*\([A-Z0-9]\{8\}\)[[:blank:]]*\(P[0-9]\{2\}\).*[.]PADM(\([^)]*\)).*/\1 \2 \3/p
       }' YourFile
    

    OBA、IBA、IOA 通用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      • 1970-01-01
      相关资源
      最近更新 更多