¿Cómo eliminar la línea si es más larga que XY?

21

¿Cómo puedo eliminar una línea si es más larga que, por ejemplo, 2048 caracteres?

LanceBaynes
fuente
¿Insiste en usar sed? Esto es fácil, por ejemplo en python. Y sin duda aún más fácil en perl. Aunque la pregunta no está terriblemente bien definida. ¿Copiar un archivo, eliminar todas las líneas más largas que 2048, o algo más?
Faheem Mitha

Respuestas:

22
sed '/^.\{2048\}./d' input.txt > output.txt
forcefsck
fuente
3
Recibo el mensaje de error sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
miércoles
1
@wedi probablemente desee instalar la versión GNU en lugar de la versión BSD que se incluye con Mac. Esto es fácil con brew
Freedom_Ben
La pregunta dice "si es más largo que XY (por ejemplo, 2048 caracteres)". Entonces debe ser> 2048 y no => 2048
ajcg
1
@ajcg, es> 2048. Observe que hay un período adicional al final de la expresión regular para que coincida con el carácter 2049.
forcefsck
@forcefsck y no sería mejor si lo quitas "^"? (con su comando solo está eliminando líneas que "comienzan con XYZ", pero si XYZ está en otra parte de la línea, entonces no lo elimina)
ajcg
7

Aquí hay una solución que elimina líneas que tienen 2049 o más caracteres:

sed -E '/.{2049}/d' <file.in >file.out

La expresión /.{2049}/dcoincidirá con cualquier línea que contenga al menos 2049 caracteres y los elimine de la entrada, produciendo solo una línea más corta en la salida.

Con awklíneas de impresión de longitud 2048 o menor:

awk 'length <= 2048' <file.in >file.out

Imitando la sedsolución literalmente con awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out
Kusalananda
fuente
1
Recibo el mensaje de error sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
miércoles
1
@wedi Ahora actualizado y probado en macOS Mojave.
Kusalananda
2

Algo como esto debería funcionar en Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()
Faheem Mitha
fuente
1
Personalmente, @Faheem, prefiero tu respuesta. La razón es que fue muy fácil para mí convertirlo en 'eliminar todas las líneas más pequeñas que x'. No uso Python todo el tiempo, pero cuando lo hago, siempre siento que debería aprenderlo bien.
ixtmixilix
@ixtmixilix: Sí, usar un lenguaje con todas las funciones como Python es bastante flexible. Gracias por el comentario.
Faheem Mitha
2
perl -lne "length < 2048 && print" infile > outfile
MaratC
fuente
+1 El -lno es necesario, sin embargo.
Joseph R.
No funciona para mi Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
Mié
Puedes intentarlo length($_) > 2048 && print. lengthes un atajo de length($_)todos modos.
MaratC
0

Las respuestas anteriores no me funcionan en Mac OS X 10.9.5.

El siguiente código funciona:

sed '/.\{2048\}/d'.

Aunque no se le solicite, pero se proporciona como referencia, lo contrario se puede lograr con el siguiente código:

sed '/.\{2048\}/!d'.

Wedi
fuente
lol, pero sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
alex grey
Ah Instalé la versión GNU en lugar de la versión BSD que viene con Mac como @Freedom_Ben sugirió anteriormente. Pero Kusalananda encontró el interruptor para habilitar la expresión regular extendida. Por lo tanto, debe seguir con su solución si todavía tiene ese problema. ;)
Mié
0

Con gnu-sed, puede usar la bandera -r para evitar escribir las barras diagonales inversas y una coma para definir un intervalo abierto:

sed -r  "/.{2049,}/d" input.txt > output.txt

con:

  • x {2049} significa exactamente 2049 xs
  • x {2049,3072} que significa desde 2049 a 3072 xs
  • x {2049,} significa al menos 2049 xs
  • x {, 2049} que significa como máximo 2049 xs

Para los intervalos, para no coincidir con patrones más grandes, necesitaría anclas de línea como

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
usuario desconocido
fuente