Como obter a segunda coluna da saída do comando?

152

A saída do meu comando é algo como:

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

A primeira coluna é sempre um número, seguido de um espaço e, em seguida, uma sequência de aspas duplas.

Meu objetivo é obter apenas a segunda coluna, como:

"A B"
"C"
"D"

Eu pretendia usar <some_command> | awk '{print $2}'para fazer isso. Mas a questão é que alguns valores na segunda coluna contêm espaço (s), que é o delimitador padrão para awkseparar os campos. Portanto, a saída está confusa:

"A
"C"
"D"

Como obtenho o valor da segunda coluna (com aspas emparelhadas) corretamente?

Qiang Xu
fonte
1
Tentei usar awk '{$1=""; print $0}', mas ele ainda tem um caractere de espaço em branco à esquerda. Pode ser removido por sed '/^ //'. No entanto, isso poderia ser feito awk?
Qiang Xu

Respostas:

29

Ou use sed & regex.

<some_command> | sed 's/^.* \(".*"$\)/\1/'
catay
fonte
Shorter cmd como você não precisa iniciar e marcadores finais:<some_command> | sed 's/.* \(".*"\)/\1/'
Timo
197

Use -F [field separator]para dividir as linhas em "s:

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

ou para entrada do tubo

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

resultado:

A B
C
D
Alex
fonte
3
Isso é bom, mas também quero as aspas originais. Isso poderia ser feito? Obrigado.
Qiang Xu
5
você poderia enganar, e mudança do awk de impressão para'{print "\""$2"\""}'
Alex
Sim, isso funciona. Muito obrigado, Alex! A propósito, tantas citações :)
Qiang Xu
@ Alex, você poderia explicar como usou aspas duplas e barra invertida para obter o que a operação queria.
Timo
1
@Timo A divisão de cotações e barras invertidas pode ser vista como "\"" + $2 + "\"". As aspas circundantes estão indicando algo a ser acrescentado à saída, e as aspas com escape ( \") estão sendo impressas. Para ajudar a visualizar ele, este é o que olharia como se nós queria acrescentar espaços em branco ao redor $2em vez de aspas: '{print " "$2" "}'. Também podemos adicionar espaçamento de formato para facilitar um pouco o grok:'{print " " $2 " "}'
Tom
80

Se você pudesse usar algo diferente de 'awk', tente isso em vez disso

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

-d é um delimitador, -f é o campo a ser cortado e com -f2- pretendemos cortar o 2º campo até o final.

TheAshwaniK
fonte
isso me ajudou a tentar fazer o seguinte (buscar o ID de confirmação de um arquivo no git): git anota myfile.cpp | grep '2016-07' | cabeça -1 | cut -f1
serup 14/07/16
2
Isso é bom, mas não funciona se o delimitador tiver mais de um caractere. É aí que a solução awk vem a calhar
smac89
2
Por que um espaço não é usado depois -d? Parece um pouco estranho dessa maneira.
Chris Stryczynski
43

Isso deve funcionar para obter uma coluna específica da saída do comando "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

Isso vai imprimir a terceira coluna

hemanto
fonte
Você já viu imagens do docker | awk '{print $ 5}'?
Shashi Ranjan
17

Você não precisa de awk para isso. Usar o readshell Bash deve ser suficiente, por exemplo

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

ou:

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

Se você possui o GNU awk, esta é a solução que você deseja:

$ awk '{print $1}' FPAT='"[^"]+"' file
"A B"
"C"
"D"
Chris Seymour
fonte
0
awk -F"|" '{gsub(/\"/,"|");print "\""$2"\""}' your_file
Vijay
fonte
0
#!/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

Então, supondo que você nomeie o script como co, digamos, faça algo assim para obter o tamanho dos arquivos (o exemplo assume que você está usando Linux, mas o script em si é independente do sistema operacional): -

ls -lh | co 5

Andy Southwell
fonte