【问题标题】:How to get the second column from command output?如何从命令输出中获取第二列?
【发布时间】:2013-04-14 18:06:57
【问题描述】:

我的命令输出类似于:

1540 "A B"
   6 "C"
 119 "D"

第一列总是一个数字,后跟一个空格,然后是一个双引号字符串。

我的目的是只获取第二列,例如:

"A B"
"C"
"D"

我打算使用<some_command> | awk '{print $2}' 来完成此操作。但问题是,第二列中的某些值包含空格,这恰好是 awk 分隔字段的默认分隔符。因此,输出混乱:

"A
"C"
"D"

如何干净利落地获取第二列的值(带双引号)?

【问题讨论】:

  • 我尝试使用awk '{$1=""; print $0}',但它仍然有一个前导空格字符。它可以被sed '/^ //' 删除。然而,这可以用awk 完成吗?

标签: shell awk ksh


【解决方案1】:

使用-F [field separator] 分割"s 上的行:

awk -F '"' '{print $2}' your_input_file

或用于管道输入

<some_command> | awk -F '"' '{print $2}'

输出:

A B
C
D

【讨论】:

  • 这很好,但我也想要原始的周围引号。能做到吗?谢谢。
  • 你可以作弊,把 awk 的打印改成'{print "\""$2"\""}'
  • 是的,这行得通。非常感谢,亚历克斯!顺便说一句,这么多引用,:)
  • @Alex,你能解释一下你是如何使用双引号和反斜杠来得到 op 想要的吗?
  • @Timo 引号和反斜杠分解可以设想为"\"" + $2 + "\""。周围的引号表示要附加到输出的内容,并且正在打印转义的引号 (\")。为了帮助可视化它,如果我们想在$2 周围添加空格而不是引号,这就是它的样子:'{print " "$2" "}'。我们还可以添加格式间距以使其更容易理解:'{print " " $2 " "}'
【解决方案2】:

如果您可以使用 'awk' 以外的其他内容,请尝试使用此方法

echo '1540 "A B"' | cut -d' ' -f2-

-d 是分隔符,-f 是要剪切的字段,使用 -f2- 我们打算剪切第二个字段,直到结束。

【讨论】:

  • 这帮助我尝试执行以下操作(在 git 中获取文件的提交 ID): git annotate myfile.cpp | grep '2016-07' |头-1|剪切-f1
  • 这很好,但如果分隔符长度超过一个字符,则不起作用。这就是 awk 解决方案派上用场的地方
  • 为什么-d后面没有空格?那样看起来有点奇怪。
  • 如果您的输出有不止一列,而您只需要第二列,请使用cut -d' ' -f2
【解决方案3】:

这应该可以从命令输出“docker images”中获取特定列:

REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE
ubuntu                              16.04               12543ced0f6f        10 months ago       122 MB
ubuntu                              latest              12543ced0f6f        10 months ago       122 MB
selenium/standalone-firefox-debug   2.53.0              9f3bab6e046f        12 months ago       613 MB
selenium/node-firefox-debug         2.53.0              d82f2ab74db7        12 months ago       613 MB


docker images | awk '{print $3}'

IMAGE
12543ced0f6f
12543ced0f6f
9f3bab6e046f
d82f2ab74db7

这将打印第三列

【讨论】:

  • 你看过 docker 镜像了吗? awk '{print $5}' ?
  • @ShashiRanjan 不,那是什么?
【解决方案4】:

或者使用 sed 和正则表达式。

<some_command> | sed 's/^.* \(".*"$\)/\1/'

【讨论】:

  • 较短的 cmd,因为您不需要开始和结束标记:&lt;some_command&gt; | sed 's/.* \(".*"\)/\1/'
【解决方案5】:

你不需要 awk。在 Bash shell 中使用 read 就足够了,例如

some_command | while read c1 c2; do echo $c2; done

或:

while read c1 c2; do echo $c2; done < in.txt

【讨论】:

    【解决方案6】:

    如果您有 GNU awk,这就是您想要的解决方案:

    $ awk '{print $1}' FPAT='"[^"]+"' file
    "A B"
    "C"
    "D"
    

    【讨论】:

      【解决方案7】:
      awk -F"|" '{gsub(/\"/,"|");print "\""$2"\""}' your_file
      

      【讨论】:

        【解决方案8】:
        #!/usr/bin/python
        import sys 
        
        col = int(sys.argv[1]) - 1
        
        for line in sys.stdin:
            columns = line.split()
        
            try:
                print(columns[col])
            except IndexError:
                # ignore
                pass
        

        然后,假设您将脚本命名为 co,例如,执行以下操作来获取文件的大小(该示例假设您使用的是 Linux,但脚本本身是独立于操作系统的):-

        ls -lh | co 5

        【讨论】:

          猜你喜欢
          • 2019-05-18
          • 1970-01-01
          • 2018-06-20
          • 1970-01-01
          • 1970-01-01
          • 2016-04-30
          • 2017-11-11
          • 2013-07-12
          • 2018-02-11
          相关资源
          最近更新 更多