【问题标题】:get columns contain specific string获取包含特定字符串的列
【发布时间】:2017-08-02 07:01:54
【问题描述】:

我有一个类似如下的文件:

cat text.txt
a1       a2       j
h       a1
k       p       a1       a2      a3

我想得到的列比所有匹配字符串“a”。

a1    a2
a1
a1    a2    a3

我正在尝试使用 awk,但只得到最后一个,而不是全部。

awk '{for(i=1;i<=NF;i++){if($i~/^a/){arr=$i}} print arr}' text.txt
a2
a1
a3

【问题讨论】:

  • 您有什么尝试过的需要帮助的事情吗?
  • awk '{for(i=1;i&lt;=NF;i++){if($i~/^a/){arr=$i}} print arr}' text.txt 但只得到最后一个,而不是全部。
  • 你应该把它放在你的问题中。
  • @hope:您错过了将匹配字段附加到变量 arrsee corrected code below

标签: python awk text-processing


【解决方案1】:

使用

输入

$ cat file
a1       a2       j
h       a1
k       p       a1       a2      a3

输出

$ awk '{s="";for(i=1;i<=NF;i++)if($i~/^a/)s=(s?s OFS:"") $i; if(s)print s}' file
a1 a2
a1
a1 a2 a3

说明

awk '{                                        # call awk
        s="";                                 # set var s with null value, in fact it reset variable s for each line/record/row read by awk 
        for(i=1;i<=NF;i++)                    # NF gives no of fields in record, so loop through first to last field of current record/line/row
                if($i~/^a/)s=(s?s OFS:"") $i; # if current field($i) starts with a then, if variable s has something before then concatenate s with output separator and current field value, else set s with current field


        if(s)                                 # if s has something then  
            print s                           # print s
      }
     ' file

阅读更多关于ternary operator

s = ( s ? s OFS : "" ) $i;

      ^
  Above one is same as below

# Or if(s != "") or if(length(s))
if(s)
{
    s = s OFS $i
}else
{
    s = $i
}

【讨论】:

  • 不错。最好有详细的解释。
  • 祝你好运。
【解决方案2】:

get columns contain specific string的正确方式是:

$ awk '{
    c=0
    for (i=1;i<=NF;i++) {
        if ( index($i,"a") ) {
            printf "%s%s", (c++ ? OFS : ""), $i
        }
    }
    if (c) {
        print ""
    }
}' file
a1 a2
a1
a1 a2 a3

这适用于出现在任何字段的任何位置的任何字符串“a”,当目标字符串包含正则表达式元字符时不会产生错误匹配,当不匹配时不会打印空行。

【讨论】:

    【解决方案3】:

    我建议你阅读 Python 文档中的Reading and Writing Files。试一试。打开文件,并使用for 循环将每行的内容作为字符串获取。

    然后split字符串和filter列表得到你想要的字段,如果你想要一个字符串,使用join

    with open("tryme.txt") as f:
        for line in f:
            #split the string and filter it.
    

    尝试自己编写代码,如果遇到困难,请询问。StackOverflow 不是设计、编码或教程服务。

    【讨论】:

    • 首先,感谢您的建议。我总共学习了一周的python。所以,你的建议对我来说更重要。以下是我的尝试结果,它也可以达到我的目的。你还有什么建议吗。 with open("xxxx_C.csv") as f: for line in f : print line a=line.split(";") print a b=filter(lambda k: 'GO:' in k, a) print b
    【解决方案4】:

    @hope:也可以试试:

    awk '{gsub(/[^a[0-9]]*/," ");gsub(/^[[:space:]]+|[[:space:]]+$/,"");print}'   Input_file
    

    解释:除了没有字符串的字段外,全局替换所有行中的内容。因为你没有提到是否可能有一个混合字段(可能有一个和其他东西)所以不考虑那部分,如果是混合值(字符串 a 和其他),它只会打印一个。 然后将从行开始并以空格结尾的空格替换为行中的NULL,然后打印该行。

    【讨论】:

      【解决方案5】:
      awk '{j=0;for(i=1;i<=NF;i++)if($i~/^a/){printf (++j<2?"":FS) $i};print""}' urfile
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      • 即使没有以a开头的单个字段也会打印换行符
      • 不打印包含字符串a 的字段,它打印以正则表达式a 开头的字段。 OPs 示例输入/输出隐藏了这些区别。此外,除非您有一个非常具体的目的并完全了解风险,否则永远不要这样做printf $i。总是做printf "%s", $i。想象一下,当有一天$i 最终包含诸如%s 之类的printf 格式字符时针对数据运行时会有什么不同。
      猜你喜欢
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 2021-12-31
      • 2022-01-12
      • 2021-03-21
      • 2020-08-26
      • 1970-01-01
      相关资源
      最近更新 更多