Como incrementar o contador de linha para substituições de início de linha por AWK /…?

8

Primeiro pensei em SED ( sed "s/^/COUNTER \&/" /tmp/1.tex ), mas ele foi projetado para uma única linha, e não consigo incrementar o contador em si por sed, pensando agora em awk porque tenho ótimas experiências com gawk em abordagens integradas. Dados

What & South Dragon & North Dragon    & 5 \ \hline
What & South Dragon & North Dragon    & 5 \ \hline
What & South Dragon & North Dragon    & 5 \ \hline

Saída esperada

1 & What & South Dragon & North Dragon    & 5 \ \hline
2 & What & South Dragon & North Dragon    & 5 \ \hline
3 & What & South Dragon & North Dragon    & 5 \ \hline

OS: Debian 8.5

    
por Léo Léopold Hertz 준영 27.12.2016 / 20:59

4 respostas

10

nl é um utilitário para numerar as linhas de um arquivo.Usage:

nl /path/to/file

No seu caso específico:

$ nl  -s ' & ' input.txt                                                                                                 
     1 & What & South Dragon & North Dragon    & 5 \ \hline
     2 & What & South Dragon & North Dragon    & 5 \ \hline
     3 & What & South Dragon & North Dragon    & 5 \ \hline
    
por 27.12.2016 / 21:36
10

Isso alcança o que você procura. (assim como awk '$0=NR" & "$0' filename , mas isso é um pouco enigmático)

awk '{print NR,"&",$0}' filename
1 & What & South Dragon & North Dragon    & 5 \ \hline
2 & What & South Dragon & North Dragon    & 5 \ \hline
3 & What & South Dragon & North Dragon    & 5 \ \hline

Ou se sed preferível, isso dá o mesmo resultado.

sed = filename | sed 'N;s/\n/ \& /'

perl se aproxima.

perl -pe '$_="$. & $_"' filename
perl -pe 's/^/$. & /' filename
    
por 27.12.2016 / 21:23
3

O Python pode ser uma boa ferramenta alternativa para isso:

$ python -c "import sys;lines=[str(i)+' & '+l for i,l in enumerate(sys.stdin,1)]; print ''.join(lines)" < input.txt      
1 & What & South Dragon & North Dragon    & 5 \ \hline
2 & What & South Dragon & North Dragon    & 5 \ \hline
3 & What & South Dragon & North Dragon    & 5 \ \hline

A maneira como isso funciona é que redirecionamos o texto para o stdin do python e lemos as linhas a partir dele. A função enumerate() é o que fornece a contagem de linhas, com sys.stdin especificado como entrada e 1 é o índice inicial. O resto é simples - criamos uma lista de novas strings ao converter o índice como string unida com ' & ' string e a própria linha. Finalmente, tudo que é remontado da lista em um teste pela função ''.join() .

Como alternativa, aqui está uma versão com várias linhas para um arquivo de script ou simplesmente para legibilidade:

#!/usr/bin/env python
import sys

for index,line in enumerate(sys.stdin,1):
    print str(index) + ' & ' + line.strip()

Funciona da mesma forma:

$ ./line_counter.py  < input.txt                                                                                         
1 & What & South Dragon & North Dragon    & 5 \ \hline
2 & What & South Dragon & North Dragon    & 5 \ \hline
3 & What & South Dragon & North Dragon    & 5 \ \hline

Mas se você preferir fazer isso no bash, isso também pode ser feito:

$ counter=1; while read line ; do printf "%s & %s\n" "$counter" "$line" ; counter=$(($counter+1)) ; done < input.txt
1 & What & South Dragon & North Dragon    & 5 \ hline
2 & What & South Dragon & North Dragon    & 5 \ hline
3 & What & South Dragon & North Dragon    & 5 \ hline
    
por 28.12.2016 / 08:37
2

Esta também é uma opção que usa cat -n com a numeração automática:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
    
por 28.12.2016 / 11:51