Ordene palabras en cada línea y edite el archivo en el lugar

Ordene palabras en cada línea y edite el archivo en el lugar

Leo un archivo línea por línea, edito cada línea y las guardo en un archivo separado.

while read -r line
do
   newline=$(echo $line | sed -r 's/\</\n/g' | sort | tr '\n' ' ')
   echo "$newline" >> newfile
done < "$filename"

Pero quiero reemplazar las líneas originales con respecto a $filenamelas nuevas líneas. Leí que podría usar cat filename... | xargs -n1 commando sed -i ...pero hasta ahora mis pistas han fallado.

Aquí hay un ejemplo de entrada:

1.e4 e5 2.Nf3 Nc6 3.
1.d4 d5 2.e4 dxe4 3.
1.e4 e5 2.Nf3 Nf6 3.

y este es el resultado esperado:

 1. 2. 3. e4  e5  Nc6  Nf3  
 1. 2. 3. d4  d5  dxe4  e4  
 1. 2. 3. e4  e5  Nf3  Nf6 

Respuesta1

Podrías usar sponge, como se menciona enUn programa que podría almacenar en búfer stdin o archivo. Puedes canalizar todo el bucle hacia él, de la misma manera que se redirige la entrada a él:

while read -r line ; do 
    echo "$line" | sed -r 's/\</\n/g' | sort | tr '\n' ' ' ; 
    echo
done < filename | sponge filename

Con Perl, se podría hacer lo mismo con esto (la cantidad de espacios en blanco es diferente):

perl -Mlocale -i -lne 'print join " ", sort split/(?<=\.)| /' filename

Respuesta2

awkacercarse:

awk 'BEGIN{IGNORECASE=1;}{ gsub(/\./,". ", $0); split($0, w, " "); 
     asort(w);l=""; for(i in w) {l=l" "w[i]} print l}' file

La salida:

1. 2. 3. e4 e5 Nc6 Nf3
1. 2. 3. d4 d5 dxe4 e4
1. 2. 3. e4 e5 Nf3 Nf6

IGNORAR CASOse puede configurar en la línea de comando o en unCOMENZARregla

split($0, w, " ");- divide la línea en palabras separadas

asort(w);- ordena valores de matriz (palabras)

for(i in w) {l=l" "w[i]}- concatenar palabras ordenadas en una sola línea

información relacionada