¿Cómo incrementar el contador de línea para los reemplazos de inicio de línea por AWK / ...?


9

Primero pensé en SED ( sed "s/^/COUNTER \&/" /tmp/1.tex), pero está diseñado para una sola línea, y no puedo incrementar el contador por sí mismo, así que ahora pienso awkporque tengo grandes experiencias con gawkenfoques integrados. Datos

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

Rendimiento esperado

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

SO: Debian 8.5

Respuestas:


11

nl es una utilidad para numerar las líneas de un archivo.

nl /path/to/file

En tu 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

¿Cómo puedes combinar esto con el contador de preappending y el ampersand? - - Funciona para el mostrador, pero no estoy seguro si también para este último.
— Léo Léopold Hertz 준영

3
nl -s ' &' /path/to/file. -sespecifica qué separa los números del cuerpo del archivo de entrada.
— DopeGhoti

1
nldifiere de cat -ny la awksolución en que no
— numera

10

Esto logra lo que buscas. (como lo hace awk '$0=NR" & "$0' filename, pero eso es un poco críptico)

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

O si es sedpreferible, esto da el mismo resultado.

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

perl enfoques.

perl -pe '$_="$. & $_"' filename
perl -pe 's/^/$. & /' filename

¿Cómo encontraste esta sintaxis sed = filename | ...? - - No sabía que puedes usar sed con el equalsímbolo. - - ¿Puede su seddeclaración funcionar en entornos dinámicos? ¿Alguna debilidad?
— Léo Léopold Hertz 준영

1
@ LéoLéopoldHertz 준영 Busqué en la página de manual, el =operador está en la sección "Comandos de cero o una dirección".
— Sergiy Kolodyazhnyy

Sí, = Print the current line number. Por lo tanto, la función está incorporada en sed. ¡Agradable!
— Léo Léopold Hertz 준영

3

Python puede ser una buena herramienta alternativa para esto:

$ 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 forma en que esto funciona es que redirigimos el texto al stdin de Python y leemos líneas desde allí. enumerate()La función es lo que da el recuento de líneas, sys.stdinespecificado como entrada y 1es el índice inicial. El resto es simple: hacemos una lista de nuevas cadenas al convertir el índice como una cadena unida con una ' & 'cadena y la línea misma. Finalmente, todo lo que la función vuelve a montar de la lista en una prueba ''.join().

Alternativamente, aquí hay una versión de varias líneas para un archivo de script o simplemente para facilitar la lectura:

#!/usr/bin/env python
import sys

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

Funciona igual:

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

Pero si prefieres hacerlo en bash, entonces eso también se puede hacer:

$ 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 준영 Bueno, si tuviera que hacer eso sin enumerar, necesitaría una variable que rastree el número de líneas, y necesito iniciar esa variable e incrementarla cada vez. Usando enumerate()ahorra como 3 líneas de código. Es útil cuando se trata con otras cosas, como procesar elementos en listas. Ver docs.python.org/2/library/functions.html#enumerate
— Sergiy Kolodyazhnyy

@ LéoLéopoldHertz 준영 si entiendes usar el contador como lo hago yo, por bashejemplo, entonces siéntete libre de usar eso :) Por experiencia me pareció enumerate()más elegante, pero esa es solo mi opinión. Por supuesto, use otro método si cree que está más claro
— Sergiy Kolodyazhnyy

OK, enumeratees más claro que la instanciación variable. ¿Puede la expresión lambda ahorrar algo de espacio?
— Léo Léopold Hertz 준영

@ LéoLéopoldHertz could Podría ahorrar espacio en una secuencia de comandos larga, pero en este caso, simplemente no veo cómo eso podría ayudar.
— Sergiy Kolodyazhnyy

2

Esta también es una opción que se usa cat -ncon la numeración automática:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.