Ordene as palavras em cada linha, editando o arquivo no local

1

Eu leio um arquivo linha por linha e edito cada linha e salvo essas linhas em um arquivo separado.

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

Mas quero substituir as linhas originais em relação a $filename pelas novas linhas. Eu li que eu poderia usar cat filename... | xargs -n1 command ou sed -i ... , mas até agora minhas trilhas falharam.

Aqui está uma entrada de exemplo:

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

e esta é a saída esperada:

 1. 2. 3. e4  e5  Nc6  Nf3  
 1. 2. 3. d4  d5  dxe4  e4  
 1. 2. 3. e4  e5  Nf3  Nf6 
    
por Hölderlin 12.04.2017 / 21:33

2 respostas

2

Você pode usar sponge , conforme mencionado em Um programa que pode armazenar em buffer stdin ou arquivo . Você pode canalizar todo o loop para ele, da mesma forma que a entrada é redirecionada para ele:

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

Com o Perl, o mesmo poderia ser feito com isso (a quantidade de espaço em branco é diferente):

perl -Mlocale -i -lne 'print join " ", sort split/(?<=\.)| /' filename
    
por 12.04.2017 / 21:58
2
abordagem

awk :

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

A saída:

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

IGNORECASE pode ser definido na linha de comando ou em uma regra BEGIN

split($0, w, " "); - divide a linha em palavras separadas

asort(w); - classifica os valores da matriz (palavras)

for(i in w) {l=l" "w[i]} - concatenando palavras classificadas em uma única linha

    
por 12.04.2017 / 22:52