awk -F_ '{print $(NF-1), $0}' | sort -k1,1 -n | cut -d' ' -f2-
Isso usa awk
com _
como o separador de campo para copiar o segundo último campo ( datetime ) para o início da linha e, em seguida, usa sort
para classificar a entrada numericamente apenas nesse campo, seguido por cut
para remover o campo extra.
Exemplo de saída com sua entrada de amostra salva em um arquivo chamado file
:
$ awk -F_ '{print $(NF-1), $0}' file | sort -k1,1 -n | cut -d' ' -f2-
swid_state_definition_user_20171227162839_6515.log
package_user_20171227162858_7082.log
swid_appsrv_stop_user_20171227172258_27116.log
swid_state_definition_user_20171227172344_322.log
package_user_20171227172610_16198.log
swid_ds_install_user_20171227172654_20425.log
swid_ds_install_user_20171227172732_23839.log
package_user_20171227172949_5627.log
package_user_20171227233634_23845.log
Isso pressupõe que o datetime sempre estará no segundo último campo. Se isso não for não , então se você estiver usando o GNU awk, você pode capturar o padrão que parece como um datetime, e prefixar isso ao início da linha:
$ awk -F_ '{match($0,"_(20[0-9]{12})_",dt); print dt[1], $0}' file |
sort -k1,1 -n | cut -d' ' -f2-
mas eu estaria inclinado a usar perl
neste caso.
A função match()
do GNU awk recebe um terceiro argumento opcional, o nome de uma variável de matriz para armazenar todas as correspondências capturadas. Neste caso, haverá apenas uma captura, para que seja armazenada no primeiro elemento. da matriz, por exemplo %código%. IIRC, POSIX awk ainda não tem como capturar combinações de regex.
BTW, a suposição agora é que o ano é > = 2000. Ajuste o regex para se adequar se isso não for sempre verdadeiro para seus dados de entrada.