Como usar ":" como separador de campos do awk?

243

Dado o seguinte comando:

echo "1: " | awk '/1/ -F ":" {print $1}'

por que o awk output:

1: 
user173446
fonte

Respostas:

382

"-F" é um argumento de linha de comando que não é sintaxe do awk, tente:

 echo "1: " | awk -F  ":" '/1/ {print $1}'
Jürgen Hötzel
fonte
42
A pergunta do ignorante aqui: a parte / 1 / é para o awk processar apenas linhas (ou registros para ser mais preciso) que contenham o número 1, certo?
rantsh
3
Parece que a sintaxe do @rantsh Awk (pattern){action}. Se pattern(principalmente uma declaração condicional) for verdadeira , actionserá executada. Se patternnão estiver disponível, trueestá implícito. Aqui patternestá o /1/que estados é regex 1correspondido no registro atual$0
kvantour
62

Se você quiser fazer isso programaticamente, poderá usar a FSvariável:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Observe que, se você o alterar no loop principal, e não no BEGINloop, isso afetará a próxima linha lida, pois a linha atual já foi dividida.

Pausado até novo aviso.
fonte
35

Você tem várias maneiras de definir :como separador:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Todos eles são equivalentes e, para um, retornará 1para uma entrada de amostra "1: 2: 3":

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1
fedorqui 'Então pare de prejudicar'
fonte
qual é a maneira preferida? Presumo que o exemplo final com a BEGINinstrução seja o mais correto (sendo consistente com a awksintaxe geral ).
1
@randomware todos eles estão bem. Eu costumo usar BEGINse eu usar um arquivo para armazenar a coisa toda, enquanto -Fé útil com one-liners.
fedorqui 'Então, pare de prejudicar' 01/06/19
1
Deve-se dizer que existem diferenças sutis entre o terceiro caso e todos os outros. Exemplo: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileeawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour
@kvantour bom ponto. Eu apenas perguntei sobre isso em Por que o separador de campos é levado em consideração de maneira diferente se definido antes ou depois da expressão? .
fedorqui 'SO stop prejudying'
12

-Fé um argumento para awksi mesmo:

$echo "1: " | awk -F":" '/1/ {print $1}'
1
danben
fonte
2
Não há necessidade de citar dois pontos.
ceving
6

Você também pode usar uma regex como um separador de campos; o seguinte imprimirá "barra" usando uma regex para definir o número "10" como um separador.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'
Zlemini
fonte
4

Não há necessidade de escrever isso. Basta colocar o separador de campos desejado com a opção -F no comando awk e o número da coluna que você deseja imprimir segregado conforme o separador de campos mencionado.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1
Bhavuk Taneja
fonte
4

O AWK funciona como intérprete de texto que segue a linha em todo o documento e segue em campo para cada linha, portanto, $ 1, $ 2 .. $ n são referências aos campos de cada linha ($ 1 é o primeiro campo, $ 2 é o segundo campo e assim por diante ...) Você pode definir um separador de campos usando a opção "-F" na linha de comando ou entre dois colchetes com "FS = ...". Agora considere a resposta de "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

Acima dos limites do campo são definidos por ":", então temos dois campos $ 1, que é "1" e $ 2, que é o espaço vazio. Depois, vem a expressão regular "/ 1 /" que instrui o filtro a exibir apenas o primeiro campo quando o intérprete se depara com uma linha que contém essa expressão (quero dizer 1); A saída do comando "echo" é uma linha que contém "1" para que o filtro funcione ...

Ao lidar com o seguinte exemplo:

echo "1: " | awk '/1/ -F ":" {print $1}'

A sintaxe é confusa e o intérprete optou por ignorar a parte F ":" e alterna para o divisor de campo padrão, que é o espaço vazio, gerando "1:" como o primeiro campo e não haverá um segundo campo!

A resposta de JUERGEN contém a boa sintaxe ...

jihed gasmi
fonte
2

Ou você pode usar:

echo "1: " | awk  '/1/{print $1-":"}' 

Esta é uma equação realmente engraçada.

Vonton
fonte
1
o que /1/significa
Encontre um padrão. Neste caso "1"
José Dias