Eu tenho um arquivo de campo de largura fixa que estou tentando classificar usando o utilitário de classificação UNIX (Cygwin, no meu caso).
O problema é que há um cabeçalho de duas linhas na parte superior do arquivo que está sendo classificado na parte inferior do arquivo (pois cada linha de cabeçalho começa com dois pontos).
Existe uma maneira de dizer à classificação "passar as duas primeiras linhas entre não classificados" ou de especificar uma ordem que classifique as linhas de dois pontos no topo - as linhas restantes são sempre iniciadas com um numérico de 6 dígitos (que é na verdade a chave I estou classificando) se isso ajudar.
Exemplo:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00
deve classificar para:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
unix
sorting
command-line
Rob Gilliam
fonte
fonte
Respostas:
Os parênteses criam um subshell, envolvendo o stdout para que você possa canalizá-lo ou redirecioná-lo como se tivesse vindo de um único comando.
fonte
tee >(head -n $header_size) | tail -n +$header_size | sort
, mas a cabeça parece correr atrás dotail|sort
tubo, então o cabeçalho acaba impresso no final. Isso é determinístico ou uma condição de corrida?cat
para redirecionar o stdin para um arquivo temporário e, em seguida, executar o comando acima nesse novo arquivo, mas está começando a ficar feio o suficiente que é provavelmente melhor usar uma das soluções baseadas em awk fornecidas em as outras respostas.Se você não se importa de usar
awk
, pode aproveitarawk
capacidades de tubulação integradas dopor exemplo.
Isso imprime as duas primeiras linhas textualmente e canaliza o resto através
sort
.Observe que isso tem a vantagem muito específica de poder classificar seletivamente as partes de uma entrada canalizada. todos os outros métodos sugeridos apenas classificarão arquivos simples que podem ser lidos várias vezes. Isso funciona em qualquer coisa.
fonte
$0
,print
é o suficiente.Esta é uma versão que funciona em dados canalizados:
Se o seu cabeçalho tiver várias linhas:
Esta solução é daqui
fonte
extract_data | (read h; echo "$h"; sort)
, é curto o suficiente para lembrar. seu exemplo cobre mais casos extremos. :) Esta é a melhor resposta. funciona em tubos. não awk.extract_data | (read; sort)
Em casos simples,
sed
pode fazer o trabalho com elegância:ou equivalente,
A chave está em
1q
- imprime a primeira linha (cabeçalho) e sai (deixando o resto da entrada parasort
).Para o exemplo dado,
2q
fará o truque.A
-u
opção (sem buffer) é necessária para aquelessed
s (notavelmente, GNU's) que, de outra forma, leriam a entrada em blocos, consumindo, assim, os dados que você deseja acessarsort
.fonte
Você pode usar
tail -n +3 <file> | sort ...
(tail produzirá o conteúdo do arquivo da 3ª linha).fonte
exemplo:
fonte
Leva apenas 2 linhas de código ...
Para dados numéricos, -n é obrigatório. Para classificação alfa, o -n não é necessário.
Arquivo de exemplo:
$ cat test.txt
Resultado:
$ cat a.tmp
fonte
Então aqui está uma função bash onde os argumentos são exatamente como sort. Arquivos e canais de suporte.
Como funciona. Esta linha verifica se há pelo menos um argumento e se o último argumento é um arquivo.
Isso salva o arquivo para separar o argumento. Já que estamos prestes a apagar o último argumento.
Aqui removemos o último argumento. Já que não queremos passá-lo como um argumento de classificação.
Finalmente, fazemos a parte do awk, passando os argumentos (menos o último argumento se for o arquivo) para classificar no awk. Isso foi originalmente sugerido por Dave e modificado para aceitar argumentos de classificação. Contamos com o fato de que
$file
estará vazio se estivermos encanando, portanto, será ignorado.Exemplo de uso com um arquivo separado por vírgulas.
fonte
Com Python:
fonte
Aqui está uma função shell bash derivada de outras respostas. Ele lida com arquivos e canais. O primeiro argumento é o nome do arquivo ou '-' para stdin. Os argumentos restantes são passados para classificação. Alguns exemplos:
A função shell:
fonte
Esta é a mesma resposta de Ian Sherbin, mas minha implementação é: -
fonte
Isso fará o que você quiser.
fonte