Comment incrémenter le compteur de lignes pour les remplacements de début de ligne par AWK /…?

9

J'ai d'abord pensé à SED ( sed "s/^/COUNTER \&/" /tmp/1.tex) mais il est conçu pour une seule ligne, et je ne peux pas incrémenter le compteur lui-même en sed donc awkje pense maintenant parce que j'ai de grandes expériences avec gawkdes approches intégrées. Les données

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

Production attendue

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

Léo Léopold Hertz 준영
la source

Réponses:

11

nl est un utilitaire pour numéroter les lignes d'un fichier.

nl /path/to/file

Dans votre cas spécifique:

$ 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
DopeGhoti
la source
Comment pouvez-vous combiner cela avec un compteur pré-ajouté et l'esperluette? - - Cela fonctionne pour le comptoir, mais je ne sais pas si c'est aussi pour ce dernier.
Léo Léopold Hertz 준영
3
nl -s ' &' /path/to/file. -sspécifie ce qui sépare les nombres du corps du fichier d'entrée.
DopeGhoti
1
nldiffère de cat -net la awksolution en ce qu'elle ne numérote pas les lignes vides par défaut
iruvar
10

Cela permet d'atteindre ce que vous recherchez. (comme c'est le cas awk '$0=NR" & "$0' filename, mais c'est un peu cryptique)

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 si cela est sedpréférable, cela donne le même résultat.

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

perl approches.

perl -pe '$_="$. & $_"' filename
perl -pe 's/^/$. & /' filename
Steve
la source
Comment avez-vous trouvé cette syntaxe sed = filename | ...? - - Je ne savais pas que vous pouvez utiliser sed avec equalsymbole. - - Votre sedrelevé peut-il fonctionner dans des environnements dynamiques? Des faiblesses?
Léo Léopold Hertz 준영
1
@ LéoLéopoldHertz 준영 J'ai regardé sous la page de manuel, l' =opérateur est dans la section "Commandes à zéro ou à une adresse".
Sergiy Kolodyazhnyy
Oui = Print the current line number. La fonctionnalité est donc intégrée à sed. Agréable!
Léo Léopold Hertz
3

Python peut être un bon outil alternatif pour cela:

$ 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

La façon dont cela fonctionne est que nous redirigeons le texte dans le stdin de python et lisons des lignes à partir de là. enumerate()La fonction est ce qui donne le nombre de lignes, avec sys.stdinspécifié comme entrée et 1est l'indice de départ. Le reste est simple - nous créons une liste de nouvelles chaînes en castant l'index sous forme de chaîne jointe à la ' & 'chaîne et à la ligne elle-même. Enfin, tout cela est remonté de la liste en un seul test par la ''.join()fonction.

Alternativement, voici une version multi-lignes pour un fichier de script ou simplement pour la lisibilité:

#!/usr/bin/env python
import sys

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

Fonctionne tout de même:

$ ./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

Mais si vous préférez le faire en bash, cela peut aussi être fait:

$ 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
Sergiy Kolodyazhnyy
la source
1
@ LéoLéopoldHertz 준영 Eh bien, si je devais le faire sans énumérer, j'aurais besoin d'une variable qui suit le nombre de lignes, et je dois lancer cette variable et incrémenter à chaque fois. L'utilisation enumerate()enregistre comme 3 lignes de code. Il est utile lorsque vous traitez d'autres choses, comme le traitement d'éléments dans des listes. Voir docs.python.org/2/library/functions.html#enumerate
Sergiy Kolodyazhnyy
@ LéoLéopoldHertz 준영 si vous comprenez utiliser le compteur comme je le fais dans l' bashexemple, alors n'hésitez pas à l'utiliser :) Je viens de trouver l'expérience enumerate()plus élégante, mais c'est juste mon opinion. Par tous les moyens, utilisez une autre méthode si vous pensez que c'est plus clair
Sergiy Kolodyazhnyy
OK, enumerateest plus clair que l'instanciation variable. L'expression lambda peut-elle économiser de l'espace?
Léo Léopold Hertz
@ LéoLéopoldHertz 준영 Cela pourrait économiser de l'espace dans un long script, mais dans ce cas, je ne vois pas comment cela pourrait aider.
Sergiy Kolodyazhnyy
2

Il s'agit également d'une option utilisant cat -nla numérotation automatique:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
George Vasiliou
la source