Grep la primera línea más larga
grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt
El comando es inusualmente difícil de leer sin práctica porque mezcla la sintaxis de shell y regexp.
Para explicación, usaré pseudocódigo simplificado primero. Las líneas que comienzan con ##
no se ejecutan en el shell.
Este código simplificado usa el nombre de archivo F y deja de lado las comillas y partes de expresiones regulares para facilitar la lectura.
Cómo funciona
El comando tiene dos partes, una grep
- y una wc
invocación:
## grep "^.{$( wc -L F )}$" F
Se wc
utiliza en una expansión de proceso $( ... )
, por lo que se ejecuta antes grep
. Calcula la longitud de la línea más larga. La sintaxis de expansión de shell se mezcla con la sintaxis del patrón de expresión regular de una manera confusa, por lo que descompondré la expansión del proceso:
## wc -L F
42
## grep "^.{42}$" F
Aquí, la expansión del proceso se reemplazó con el valor que devolvería, creando la grep
línea de comando que se utiliza. Ahora podemos leer la expresión regular más fácilmente: coincide exactamente desde el inicio ( ^
) hasta el final ($
) de la línea. La expresión entre ellos coincide con cualquier carácter, excepto la nueva línea, que se repite 42 veces. Combinados, es decir, líneas que consisten en exactamente 42 caracteres.
Ahora, volviendo a los comandos de shell reales: la grep
opción -E
( --extended-regexp
) permite no escapar de la {}
legibilidad. La opción -m 1
( --max-count=1
) hace que se detenga después de encontrar la primera línea. El <
en el wc
comando escribe el archivo en su stdin, para evitar wc
imprimir el nombre del archivo junto con la longitud.
¿Qué líneas más largas?
Para hacer que los ejemplos sean más legibles con el nombre de archivo que ocurre dos veces, usaré una variable f
para el nombre de archivo; Cada uno $f
en el ejemplo podría ser reemplazado por el nombre del archivo.
f="file.txt"
Mostrar la primera línea más larga : la primera línea que es tan larga como la línea más larga:
grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"
Mostrar todas las líneas más largas : todas las líneas que son tan largas como la línea más larga:
grep -E "^.{$(wc -L <"$f")}\$" "$f"
Mostrar la última línea más larga : la última línea que es tan larga como la línea más larga:
tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"
Mostrar la línea más larga individual : la línea más larga más larga que todas las demás líneas, o falla:
[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f"
(El último comando es aún más ineficiente que los demás, ya que repite el comando grep completo. Obviamente, debe descomponerse para que la salida wc
y las líneas escritas por grep
se guarden en las variables.
Tenga en cuenta que todas las líneas más largas pueden ser todas líneas Para guardar en una variable, solo se deben mantener las dos primeras líneas).