Classificando arquivos .dat por dados internos

Classificando arquivos .dat por dados internos

Eu tenho vários arquivos .dat (variáveis) com 2 informações cada, um peso e uma altura, espaço delimitado como o seguinte, onde First_Last é um nome:

18kg 1.2mem "Primeiro1_Último1.dat"

12kg 1.6mem "First2_Last2.dat" etc.

Preciso classificá-los pelo primeiro ou segundo valor de cada um. Estou pensando que preciso catcombinar todos os arquivos, retirar as unidades com um cut(não tenho tanta certeza disso) e, em seguida, adicionar os nomes dos arquivos como uma terceira coluna usando pastee, finalmente, sort -k 1,1 temp.txtno meu arquivo temporário para obter a saída desejada enquanto ainda ser capaz de acompanhar de qual arquivo veio cada valor, porque preciso dos nomes associados para abrir um arquivo diferente para cada pessoa na ordem correta. Então, meu arquivo de saída que eu usaria seria algo como

12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

Estou me perguntando se existe uma maneira melhor de fazer isso usando algo integrado ou uma propriedade do tipo de arquivo .dat que estou faltando. Ou talvez usando awk?

Responder1

Você pode usar grepe sedpara extrair a chave de classificação e especificar apenas determinadas colunas para classificação:

grep -H kg *.dat \
  | sed 's/^\([^:]\+\):\([0-9.]\+\)kg \+\([0-9.]\+\)m.*$/\2 \3 \1/' \
  | sort -t' ' -k1,2 -g

Exemplo de saída:

12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

Responder2

Se seus arquivos contiverem apenas um dado (linha) cada, algo tão simples quanto isto pode funcionar:

for x in *.dat ; do     
    echo $(< "$x") $x    # print contents of file and add the filename 
done  |  sort -nsk2,2    # stable sort by the second column.

Testei rapidamente com o GNU sort e realmente não vi as unidades ou decimais dando problemas, mas não dou garantias.

Responder3

Talvez usando (uma versão recente do) GNU awk - assumindo que por "arquivo .dat" você quer dizer apenas um arquivo de texto delimitado por espaços em branco:

awk -v sort=2 '
  {
    gsub(/kg|m/,"",$0);
    a[$sort]=$0 FS FILENAME;
  }
  END {
    PROCINFO["sorted_in"]="@ind_num_asc";
    for (i in a) print a[i];
  }' *.dat

onde a variável sortdefine a coluna para classificação ( 1ou 2); ou como uma linha

awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat

Teste

$ awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

e

$ awk -v sort=2 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
18 1.2 First1_Last1.dat
12 1.6 First2_Last2.dat

informação relacionada