Question

Je dois trouver un moyen plus rapide de numéroter les lignes d'un fichier de manière spécifique en utilisant des outils tels que awk et sed. J'ai besoin que le premier caractère de chaque ligne soit numéroté de cette façon: 1,2,3,1,2,3,1,2,3, etc.

Par exemple, si l'entrée était ceci:

line 1
line 2
line 3
line 4
line 5
line 6
line 7

La sortie doit ressembler à ceci:

1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

Voici un morceau de ce que j'ai. $ lignes est le nombre de lignes dans le fichier de données divisé par 3. Donc, pour un fichier de 21 000 lignes, je traite cette boucle 7 000 fois.

export i=0
while [ $i -le $lines ]
do
    export start=`expr $i \* 3 + 1`
    export end=`expr $start + 2`
    awk NR==$start,NR==$end $1 | awk '{printf("%d%s\n", NR,$0)}' >> data.out
    export i=`expr $i + 1`
done

En gros, cela prend 3 lignes à la fois, les numérote et s’ajoute à un fichier de sortie. C'est lent ... et puis certains! Je ne connais pas d'autre moyen plus rapide de le faire ... des idées?

Était-ce utile?

La solution

C’est lent parce que vous lisez les mêmes lignes encore et encore. De plus, vous démarrez un processus awk uniquement pour le fermer et en démarrer un autre. Mieux vaut tout faire en un coup:

awk '{print ((NR-1)%3)+1 $0}' $1 > data.out

Si vous préférez avoir un espace après le nombre:

awk '{print ((NR-1)%3)+1, $0}' $1 > data.out

Autres conseils

Essayez la nl commande.

Voir https://linux.die.net/man/1/nl . (ou un autre lien vers la documentation qui apparaît lorsque vous utilisez Google pour & "man nl &"; ou la version du texte qui s'affiche lorsque vous exécutez man nl à l'invite du shell).

  

L'utilitaire nl lit les lignes à partir du   fichier nommé ou l'entrée standard si   l'argument de fichier est omis, s'applique   un filtre de numérotation de ligne configurable   opération et écrit le résultat à la   sortie standard.

modifier: Non, c'est faux, toutes mes excuses. La commande n ne permet pas de redémarrer la numérotation toutes les <=> lignes, elle dispose uniquement d'une option pour redémarrer la numérotation après avoir trouvé un modèle. Je ferai de cette réponse une réponse du wiki de la communauté, car cela pourrait aider quelqu'un à connaître <=>.

Perl vient à l’esprit:

perl -pe '$_ = (($.-1)%3)+1 . $_'

devrait fonctionner. Il ne fait aucun doute qu’il existe un équivalent awk. Fondamentalement, ((line# - 1) MOD 3) + 1.

Cela pourrait fonctionner pour vous:

 sed 's/^/1/;n;s/^/2/;n;s/^/3/' input
awk '{printf "%d%s\n", ((NR-1) % 3) + 1, $0;}' "$@"

Python

import sys
for count, line in enumerate(sys.stdin):
    stdout.write( "%d%s" % ( 1+(count % 3), line )

Vous n'avez pas besoin de quitter bash pour cela:

i=0; while read; do echo "$((i++ % 3 + 1)) $REPLY"; done < input

Cela devrait résoudre le problème. $ _ imprimera toute la ligne.

awk '{print ((NR-1)%3+1) $_}' < input
1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

# cat input 
  line 1
  line 2
  line 3
  line 4
  line 5
  line 6
  line 7
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top