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

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

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

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

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)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.