2012-09-24 23 views
7

Soy un principiante al sed. Yo sé que es posible aplicar un comando (o un conjunto de comandos) para una determinada gama de líneas igual quesed - unir un rango de líneas seleccionadas

sed '/[begin]/,/[end]/ [some command]' 

donde [begin] es una expresión regular que designa la línea de comienzo de la gama y [end] es un habitual expresión que designa la línea final del rango (pero está incluida en el rango).

Estoy tratando de usar esto para especificar un rango de líneas en un archivo y unirlas todas en una línea. Aquí está mi mejor intento, que no funcionaba:

sed '/[begin]/,/[end]/ { 
N 
s/\n// 
} 
' 

soy capaz de seleccionar el conjunto de líneas que quiera sin ningún problema, pero me parece que no puede fusionar a todos en una sola línea. Si alguien pudiera señalarme en la dirección correcta, estaría realmente agradecido.

Respuesta

5

Una forma usando GNU sed:

sed -n '/begin/,/end/ { H;g; s/^\n//; /end/s/\n/ /gp }' file.txt 
+1

Muchas gracias. Nunca pensé usar el espacio de espera; Aprendí mucho de tu respuesta. – Setris

+0

Tenga en cuenta que esto descartará * todas las demás líneas *. Vea a continuación la respuesta de @Thor para una solución más robusta. – krlmlr

1

Me gusta su pregunta. También me gusta Sed. Lamentablemente, no sé cómo responder a tu pregunta en Sed; así que, como tú, estoy mirando aquí la respuesta.

Dado que hay una respuesta Sed ha aparecido todavía aquí, aquí es cómo hacerlo en Perl:

perl -wne 'my $flag = 0; while (<>) { chomp; if (/[begin]/) {$flag = 1;} print if $flag; if (/[end]/) {print "\n" if $flag; $flag = 0;} } print "\n" if $flag;' 
+0

Gracias a la aplicación en Perl. He querido aprenderlo por un tiempo, así que lo agregaré a mi colección de fragmentos de código para estudiar. – Setris

2

Esto es sencillo, si desea seleccionar algunas líneas y únete a ellas. Steve's usar mi respuesta o alternativa-pipe-a tr:

sed -n '/begin/,/end/p' | tr -d '\n' 

Se convierte en un poco más complicado si desea mantener las otras líneas también. Así es como yo lo haría (con sed de GNU):

join.sed

/\[begin\]/ { 
    :a 
    /\[end\]/! { N; ba } 
    s/\n/ /g 
} 

Así que la lógica aquí es:

  1. [begin] Cuando la línea se encuentra en comenzar a recoger las líneas espacio de patrón con un bucle.
  2. Cuando se encuentra [end], detenga la recolección y junte las líneas.

Ejemplo:

seq 9 | sed -e '3s/^/[begin]\n/' -e '6s/$/\n[end]/' | sed -f join.sed 

Salida:

1 
2 
[begin] 3 4 5 6 [end] 
7 
8 
9 
+0

por qué no sed -n '/ begin /,/end/p' | gzip | gunzip | tr -d '\ n' ¿mientras tanto? – Valer

+0

@Valer: No estoy seguro de entender su punto. Sin embargo, he agregado un segundo ejemplo que puede unir líneas seleccionadas conservando el resto del archivo. – Thor

Cuestiones relacionadas