shell script - o comando echo não imprime na seqüência correta

1

Eu tenho o seguinte testfile.txt :

string1 1  
string2 2  
string3 3  
string1 2  
string2 4  
string3 6  
string1 3  
string2 6  
string3 9  

Eu tenho o seguinte script:

#!bin/sh

oldstr="abc"  
while read line  
do  
    newstr=\'echo "$line" | sed 's/\(.*\)\( \)\([0-9].*\)//'\'
    echo "$oldstr vs $newstr"

    if [ $oldstr == $newstr ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       echo "new $oldstr"
    fi
done < $@ | sort
echo "done"

Eu então executo o script:

$ sh test.sh testfile.txt

e obtenha a saída:

abc vs string1  
new string1  
new string1  
new string1  
new string2  
new string2  
new string2  
new string3  
new string3  
new string3  
string1 vs string2  
string1 vs string2  
string1 vs string2  
string2 vs string3  
string2 vs string3  
string2 vs string3  
string3 vs string1  
string3 vs string1  
done

Gostaria de saber porque, como seria de esperar, o resultado seria:

abc vs string1  
new string1  
string1 vs string1
old string1  
string1 vs string1
old string1  
string1 vs string2
new string2  

e assim por diante.

  1. Por que a instrução "if" não está funcionando?
  2. Por que a impressão de eco está fora de seqüência?
por EggHead 20.01.2014 / 23:57

1 resposta

4

1) eles estão fora de ordem porque você perguntou: você prepara toda a lista e então | sort deles.

2) o teste deve ser (padrão sh sintaxe): if [ "$variable" = ... (não == ).

3) para testar coisas, use sh -xv , que imprimirá todas as linhas antes de executá-las e o resultado das expansões.

4) por que você foge dos backticks?

5) Você perdeu aspas em torno de suas variáveis

6) < $@ só funciona se houver apenas um argumento para o script.

7) usando read sem -r e sem remover os caracteres de espaço em branco de $IFS provavelmente não faz sentido aqui.

8) você não pode usar echo com dados arbitrários

9) Deve ser #!/bin/sh , não #!bin/sh

Script de trabalho:

#!/bin/sh 

oldstr="abc"  
while IFS= read -r line  
do  
    newstr='printf '%s\n' "$line" | sed 's/\(.*\)\( \)\([0-9].*\)//''
    printf '%s\n' "$oldstr vs $newstr"

    if [ "$oldstr" = "$newstr" ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       printf '%s\n' "new $oldstr"
    fi
done < "$1" 

echo "done"

Além disso, você deve alterar o arquivo de teste de entrada. O que você postou nunca aciona o caso "antigo".

Se você quiser classificar o arquivo antes de passá-lo para o loop, altere a linha while para:

sort -- "$@" | while IFS= read -r line 

e, obviamente, remova o < $@ após done :

sort -- "$@" | while IFS= read -r line  
do  
   [...]
done
    
por 21.01.2014 / 00:18