【问题标题】:Grab value from specific column in Linux从 Linux 中的特定列中获取值
【发布时间】:2020-05-21 01:05:37
【问题描述】:

我在使用 awk 命令从文本文件中的特定列中获取值时遇到问题。 这是文本文件sample.txt

      Apps                  Command            Status            From           
--------------------------------------------------------------------------------
abc-admin          vwxyz -g daemon off;        Up      1.2.3.4:82->80/tcp       
abc-app            vwxyz -g daemon off;        Exit 0  1.2.3.4:83->80/tcp       
abc-docs           aaaaaa-xxxxxxxxxx.sh        Up      1.2.3.4:3001->3000/tcp   
                   /bin/ ...                                                    
abc-mail           aaaaaa-xxxxxxxxxx.sh asd    Exit 1  1.2.3.4:3011->3000/tcp   
                   r ...                                                        
abc-encr           java -cp app:app/lib/*      Up      1.2.3.4:3011->8080/tcp   
                   enc ...                                                      
abc_admin          aaaaaa-xxxxxxxxxx.sh node   Up      1.2.3.4:3012->3000/tcp   
                   .                                                            
abc_bat            /bin/sh -c ./jkl-           Exit 2  1.2.3.4:3013->3000/tcp   
                   yyyyyyyy. ...                                                
abc_conn           /bin/sh -c ./jkl-           Up      3000/tcp                 
                   yyyyyyyy. ...                                                
abc_cust           /bin/sh -c ./jkl-           Up      1.2.3.4:3001->3000/tcp   
                   yyyyyyyy. ...                                                
abc_exp            ads start                   Up      1.2.3.4:3008->3000/tcp   
abc_gw             node .                      Up      1.2.3.4:8080->3200/tcp,  
                                                       80/tcp                   
abc_logs           /usr/local/bin/aaaaaa-      Up      1.2.3.4:5000->5000/tcp,  
                   entr ...                            5044/tcp,                
                                                       1.2.3.4:9600->9600/tcp   

我已尝试使用 awk '/abc/ {print $1,$3}' sample.txt,但它给出了以下输出:

abc-admin -g
abc-app -g
abc-docs Up
abc-mail npm
abc-encr -cp
abc_admin node
abc_bat -c
abc_conn -c
abc_cust -c
abc_exp start
abc_gw .
abc_logs Up

我刚刚意识到列之间的分隔符不是制表符 (\t)。 还有其他方法可以从第一列和第三列获取值吗? 预期结果是:

abc-admin Up
abc-app Exit 0
abc-docs Up
abc-mail Exit 1
abc-encr Up
abc_admin Up
abc_bat Exit 2
abc_conn Up
abc_cust Up
abc_exp Up
abc_gw Up
abc_logs Up

【问题讨论】:

  • 第一行的第三列 -g。看看白色空间吧!问题在于,当您将空格视为字段分隔符时,行具有不同数量的字段。在您的输入数据中,您所说的“列”表示从一行中的某个位置开始。如果这些位置没有改变(因此可以硬编码),您可以逐行读取文件并提取这些位置的字符串。

标签: linux shell awk command-line


【解决方案1】:

第一个解决方案:您能否尝试使用提供的示例进行跟踪、测试和编写。

awk '
FNR>2 && /^[^ ]/{
  if($(NF-1)~/[0-9]/){
    print $1,$(NF-2),$(NF-1)
  }
  else{
    print $1,$(NF-1)
  }
}
'  Input_file

我还认为您的最后一个字段中没有任何空格。



第二个解决方案:考虑到你的最后一个字段可以有空格,在这种情况下,可以尝试以下。

awk '
FNR>2 && /^[^ ]/{
  match($0,/ +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+.*/)
  val=split(substr($0,1,RSTART-1),array," ")
  if(array[val]~/[0-9]/){
    print $1,array[val-1],array[val]
  }
  else{
    print $1,array[val]
  }
}
'  Input_file

在我的两个解决方案中,我都认为exit 将具有数字状态,我认为这是一个公平的考虑。

【讨论】:

  • 谢谢,但它只适用于“Up”状态,而“Exit”状态只是数字(0 / 1 / 2)
  • @ZulfikarSandyPratama,它总是只有Upexit 状态吗?或者还会有更多吗?
  • @ZulfikarSandyPratama,请尝试编辑过的解决方案一次?
  • 我不确定,因为我只能在 sample.txt 文件由其他东西(不在我下面)生成之后才能读取它。顺便说一句,两种解决方案都可以正常工作。非常感谢您的帮助!
【解决方案2】:

您有固定宽度的字段。使用 GNU awk 通过 FIELDWIDTHS 指定字段宽度,然后使用 gensub() 删除它们之间的多余空格:

$ awk -v FIELDWIDTHS="19 28 8 *" 'NR<3{next} $1~/[^ ]/{print gensub(/ +/," ","g",$1" "$3)}' file
abc-admin Up
abc-app Exit 0
abc-docs Up
abc-mail Exit 1
abc-encr Up
abc_admin Up
abc_bat Exit 2
abc_conn Up
abc_cust Up
abc_exp Up
abc_gw Up
abc_logs Up

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多