
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.2m
em "Primeiro1_Último1.dat"
12kg 1.6m
em "First2_Last2.dat" etc.
Preciso classificá-los pelo primeiro ou segundo valor de cada um. Estou pensando que preciso cat
combinar 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 paste
e, finalmente, sort -k 1,1 temp.txt
no 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 grep
e sed
para 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 sort
define a coluna para classificação ( 1
ou 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