【问题标题】:AWK: Extract string between two different patternsAWK:在两个不同模式之间提取字符串
【发布时间】:2015-10-20 13:32:21
【问题描述】:

我需要提取一个包含在我的 csv 列中的字符串。

我的文件是这样的:

col1;col2;col3;cleavage=10-11;
col1;col2;col3;cleavage=1-2;
col1;col2;col3;cleavage=100-101;
col1;col2;col3;none;

所以,我的文件的分隔符是“;”但在第 4 列中,我想提取“cleavage=”和“-”之间的字符串。我所做的是在“cleavage =”之后打印 2 个字符,但并不总是 2 个字符。

我是这样做的:

awk -F "\"*;\"*" '{if (match($4,"cleavage=")) print $1";"$2";"$3";"substr($4,RSTART+9,2); else print $1";"$2";"$3";0"}' file

我发现下面的命令应该是正确的,但是我应该如何将它集成到前面的命令中呢?

awk "/Pattern1/,/Pattern2/ { print }" inputFile

感谢您的帮助! :)

编辑: 我的实际输出是

col1;col2;col3;10;
col1;col2;col3;1-;
col1;col2;col3;10;
col1;col2;col3;0;

但我想要的是:

col1;col2;col3;10;
col1;col2;col3;1;
col1;col2;col3;100;
col1;col2;col3;0;

【问题讨论】:

  • 你的预期输出是什么?
  • 字段分隔符中的转义引号是干什么用的?

标签: regex bash awk delimiter


【解决方案1】:

您可以将此 awk 与多个分隔符一起用作字段分隔符:

awk -F '[;=-]' -v OFS=';' '{print $1, $2, $3, ($4 == "cleavage") ? $5 : 0, ""}' file
col1;col2;col3;10;
col1;col2;col3;1;
col1;col2;col3;100;
col1;col2;col3;0;

编辑:如果-= 可以出现在$4 之前的字段中,那么您可以使用:

awk -F ';' -v OFS=';' '{split($4, a, /[=-]/);
           print $1, $2, $3, (a[1] == "cleavage") ? a[2] : 0, ""}' file
col1;col2;col3;10;
col1;col2;col3;1;
col1;col2;col3;100;
col1;col2;col3;0;

【讨论】:

  • 这很聪明,但是如果- or = 存在于1-3 列中,它将失败。否则这是一个很好的答案。
  • 好点@Kent,我在回答中为这种情况添加了另一种选择。
  • 太棒了!我尝试了其中的大多数,但我会说这是最好的答案。这很容易,我很容易集成到我的命令中(这要长得多)。其他的也是很好的答案,但就我而言,我认为这是最好的答案。
【解决方案2】:

不清楚确切的格式,但这适用于您的示例,并且如果 = 和 - 在其他字段中也可以使用。

GNU awk(匹配第三个参数)

awk '{match($0,/(.*);[^-0-9]*([0-9]*)[^;]*;$/,a);print a[1]";"+a[2]";"}' file

col1;col2;col3;10;
col1;col2;col3;1;
col1;col2;col3;100;
col1;col2;col3;0;

或sed

sed 's/;[^-0-9]*\([0-9]\{1,\}\)[^;]*;$/;\1;/;t;s/[^;]*;$/0;/' file

【讨论】:

    【解决方案3】:

    我想出了这一个班轮:

     awk -F';' -v OFS=";" '{sub(/cleavage=/,"",$(NF-1));
                            sub(/-.*/,"",$(NF-1));$(NF-1)+=0}7' file
    

    它给了

    col1;col2;col3;10;
    col1;col2;col3;1;
    col1;col2;col3;100;
    col1;col2;col3;0;
    

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 1970-01-01
      • 2013-05-28
      • 1970-01-01
      • 2015-05-04
      • 2012-08-18
      • 2018-11-23
      • 2023-01-13
      • 2015-05-05
      相关资源
      最近更新 更多