【问题标题】:awk one liner select only rows based on value of a columnawk one liner 根据列的值仅选择行
【发布时间】:2012-11-02 01:59:48
【问题描述】:

我想读取 filein.txt(制表符分隔)并输出一个 fileout.txt,其中仅包含与给定列的值匹配的行,并消除被查询的列。即,

filein.txt
#name\thouse\taddress
roger\tvictorian\t223 dolan st.
maggie\tfrench\t12 alameda ave.
kingston\tvictorian\t224 house st.
robert\tamerican\t22 dolan st.

假设我只想选择房屋为victorian 样式的行,那么我的 fileout.txt 应该如下所示:

fileout.txt
#name\taddress
roger\t223 dolan st.
kingston\t224 house st.

【问题讨论】:

    标签: linux unix awk


    【解决方案1】:
    awk -F"\t" '$2 == "victorian" { print $1"\t"$3 }' file.in
    

    【讨论】:

    • +1。您也可以编写print $1 FS $3,而不是硬编码打印语句中的选项卡。仅限偏好问题。
    【解决方案2】:

    您可以使用以下awk 脚本来实现:

    #!/bin/bash
    
    style="victorian"
    awk -v s_style=$style 'BEGIN{FS=OFS="\t"}
        $2==s_style {$2=""; sub("\t\t","\t"); print}'
    

    说明:

    • style="victorian":在awk 脚本之外指定您要选择的房屋样式,以便更容易维护
    • awk: 调用 awk
    • -v s_style=$style-v 选项将外部变量传递给 awk。需要为您传入的每个变量指定此项。在这种情况下,它将外部变量 $style 分配给 awk 变量 s_style
    • BEGIN{FS=OFS="\t"}:告诉 awk 输出中的字段分隔符应该是制表符,而不是默认的空格。
    • {$2==s_style {$2=""; sub("\t\t","\t"); print}}':如果第二个字段是s_style 中指定的房屋类型(在本例中为victorian),则将其删除并打印该行。

    或者,您可以这样做:

    #!/bin/bash
    
    style="victorian"
    awk -v s_style=$style 'BEGIN{FS=OFS="\t"}
        $2==s_style {print $1, $3}'
    

    但这假设您的输入文件将来不会有由制表符分隔的其他字段。

    【讨论】:

    • +1。就风格而言,我会在 BEGIN 块中使用 OFS 定义 FS 并删除 if 语句:awk -v s=$style 'BEGIN {FS=OFS="\t"} $2 == s {print $1, $3}'
    • @glennjackman 谢谢 =) 我还是 shell 脚本的新手;编辑我的答案以反映您的 cmets
    • 我修复了您上次编辑中的语法错误。使用 awk,主体由 CONDITION {ACTION} 对组成,其中仅当 CONDITION 返回 true 时才会执行 ACTION 主体。 BEGIN 块只在读取第一行之前为真,我们只想在条件“$2 == s”返回真时打印。
    • 我会完全放弃 BEGIN 块:awk '$2==s{print $1, $3}' s=$style OFS=\\t FS=\\t
    • @WilliamPursell 我还是awk 的新手,您介意指点我一些可以帮助我比较这两种方法之间差异的资源吗?
    【解决方案3】:

    使用OFS(输出字段分隔符)变量,可以避免行之间的硬编码:

    awk -F"\t" -v OFS="\t" '$2 == "victorian" { print $1,$3 }' file.in
    

    【讨论】:

      猜你喜欢
      • 2014-03-19
      • 2017-06-12
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      相关资源
      最近更新 更多