Pergunta sobre instruções de concatenação

3

Eu tenho um arquivo csv delimitado por ponto-e-vírgula e um script de shell Korn que faz alguma elaboração. Estou procurando entender o que essas duas instruções fazem no shell do Korn:

num_rec='cat test.csv |wc -l|tr -d " " | nawk '{printf("%0.6d\n",  $1) }''
num_rec='expr $num_rec + 2 | nawk '{printf("%0.6d\n",  $1) }''

Eles parecem ser duas instruções que usam a concatenação, mas qual é o resultado final? O que é "$ 1" no comando nawk?

    
por Micheal Bolton 24.05.2016 / 10:24

2 respostas

3

Vamos decompor os dois comandos

num_rec='cat test.csv |wc -l|tr -d " " | nawk '{printf("%0.6d\n",  $1) }''

é um comando composto: A | B | C | D

  • R: cat test.csv apenas filma o arquivo test.csv (e também é um UUOC, "Uso inútil de gato")
  • B: wc -l contará o número de linhas de sua entrada (stdin), que é o conteúdo do test.csv. Por isso, irá contar o número de linhas em "test.csv" [... note que se a última linha do test.csv não tiver um 'Newline' final, essa última linha não será contada . ..]
  • C: tr -d " " : tr excluirá todas as ocorrências de "" (espaço), que wc -l usa para preencher a saída dos números de linha. Isso garantirá que apenas o número (e a nova linha final) permaneça
  • e o D: nawk '{printf("%0.6d\n", $1)' final: aqui $ 1 está dentro do awk e significa "o primeiro campo da linha atual". Este nawk irá, para cada linha que receber, imprimir somente o primeiro campo e formatá-lo numericamente: como INT (% d), mas preenche com 0 no início para ter pelo menos 6 dígitos (o "." Aqui é ingnored , até onde eu sei ... compare com% 0.6f, que produz um floats com 6 dígitos após a vírgula)

A segunda linha:

num_rec='expr $num_rec + 2 | nawk '{printf("%0.6d\n",  $1) }''

Apenas adiciona 2 ao número (nota: 000008 está ok para expr, e será considerado como "8", enquanto que no shell seria visto como um número octal errado) e o formata novamente da mesma maneira.

Tudo isso pode ser reduzido para:

num_rec=$(printf "%0.6d\n" "$(( $(wc -l < test.csv) + 2 ))")

Portanto, tudo isso é: conte o número de linhas do .csv (independentemente do conteúdo da linha ...) e adicione 2, e coloque o resultado em 'num_rec' com "0" s na frente dele para ser pelo menos 6 dígitos.

ex: um arquivo test.csv de 32 linhas colocará num_rec: 000034

(aviso: 0nnnn no shell é frequentemente visto como um número Octal, então $ num_rec tem que ser tratado com muito cuidado depois ...)

    
por 24.05.2016 / 10:41
0

São comandos escritos por um novato que ou não aprendeu nada desde o início dos anos 90 ou está seguindo um HOWTO daquela época. Seria melhor escrito como:

num_rec=$(wc -l <test.csv)
num_rec=$(printf "%0.6d" $(( num_rec + 2 )) )

Isso usa a substituição de comando para obter a contagem de linha de test.cv usando wc -l (por redirecionamento, para que wc não imprime o nome do arquivo junto com a contagem de linhas).

Em seguida, ele usa a substituição de comando novamente, desta vez com printf e uma string de formatação para zerar a contagem de linhas para que tenha uma largura fixa de 6 dígitos, com aritmética de shell para adicionar 2 a $num_rec . / p>

O $1 no comando original awk referiu-se ao primeiro campo da entrada (neste caso, a contagem de linhas de wc )

    
por 24.05.2016 / 10:38

Tags