Ordenação baseada na última ocorrência de caractere

3

Eu quero classificar o arquivo com base no

  • texto antes da primeira vírgula, mas também
  • deseja uma classificação de segundo nível com base na data YYYYMMMDD na entrada de amostra:

Entrada de amostra:

AX,NO,NO,\PathAX/subj/defn/some-file-name-20151229.txt,
CXX,NO,NO,\PathCXX/subj/defn/some-file-name-20151229.txt,
CXX,YES,YES,\Path/subj/defn/some-file-20140503.txt,6
DY,YES,MAYBE,\PathDY/subj/defn/some-file-name-20140720.txt,6

Eu posso resolver a primeira parte com sort -t, -k1,1 , mas não sei como fazer a segunda parte diariamente, pois o número de traços no nome do arquivo não é fixo. Assim, não posso simplesmente especificar o número da coluna com um - como separador.

Saída desejada:

AX,NO,NO,\PathAX/subj/categ/some-file-name-20151229.txt,
CXX,YES,YES,\Path/subj/categ/some-file-20140503.txt,6
CXX,NO,NO,\PathCXX/subj/categ/some-file-name-20151229.txt,
DY,YES,MAYBE,\PathDY/subj/categ/some-file-name-20140720.txt,6

Notas:

Eu acho que ajuda:

  • O YYYYMMDD segue o último traço no nome do arquivo e antes da extensão do arquivo.
  • O traço antes de YYYYMMDD está sempre presente, pelo menos um traço.
  • Não há outros pontos no arquivo, exceto a extensão do arquivo.

Eu posso pensar em um processo de duas passagens em que o último - é substituído por algum outro caractere que não aparecerá no arquivo e, em seguida, classificar e substituir o caractere novamente por um traço, mas imaginando se há um mais fácil maneira.

Plataforma:

  • MacOS 10.9.5
por Peter Grill 20.03.2016 / 11:11

2 respostas

2

Uma abordagem geral para esse tipo de problema (classificar em um campo que não pode ser descrito como o N na linha) é reescrever as linhas para preceder as chaves de classificação (s ), em seguida, classifique e remova as chaves de classificação. Você pode usar ferramentas mais flexíveis, como sed ou awk, para determinar as chaves de classificação.

Eu não sei exatamente como você determina onde está a data. Eu vou para a última seqüência de 8 dígitos na linha, ajuste conforme necessário.

sed 's/.*\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\)/,&/; t; s/^/,/' |
sort -t, -k2,2 -k1,1 |
cut -d, -f 2-

O t; s/^/,/ bit no script sed pré-anexa uma vírgula se a linha não contiver nenhuma sequência de 8 dígitos, caso contrário, a última etapa removeria o primeiro campo separado por vírgulas.

    
por 20.03.2016 / 16:13
2

Você pode usar algo assim:

rev text | sed 's/-/,/1' | rev | sort -t, -k1,1 -k5,5 | rev | sed 's/,/-/2' | rev

em que o texto é um arquivo com o seu conteúdo. Isso funciona se houver uma vírgula em qualquer lugar após o registro de data e hora, e se não houver vírgulas no nome do arquivo.

E o que isso realmente faz?

  1. Inverta a linha
  2. mude primeiro '-' para ',' em linha invertida (isto é, finalmente, último '-' em linha real)
  3. inverta novamente para corresponder à linha real
  4. agora, classifique-o no primeiro e no quinto campo (datetime), com ',' como separador de campo
  5. inverta novamente
  6. muda a segunda ocorrência de ',' para '-' (como era antes)
  7. inverta e imprima a saída
por 20.03.2016 / 12:52

Tags