Convertendo a coluna timestamp unix epoch em cada linha usando sed ou awk

1

Eu tenho um arquivo com os seguintes dados de amostra de entrada:

1137921146.499 180900 61.153.158.197 1409 
1137921158.698 181622 61.153.158.197 1409
1137921758.163 180026 221.226.124.114 1374
1137921802.016 179485 121.13.128.132 1409

a primeira coluna é timestamp unix epoch que eu preciso converter para o formato legível humano mais eu quero que os dados sejam delimitados da seguinte forma

Sun Jan 22 01:12:26 PST 2006|180900|61.153.158.197|1409   
Sun Jan 22 01:12:38 PST 2006|181622|61.153.158.19|1409

Eu tentei adicionar delimeters usando sed 's / {1,} / | / g' e convertendo a data usando a data -d @ 1137921146.499. Mas eu sou incapaz de juntar esses dois em um comando ...

    
por Prat 23.05.2017 / 08:57

3 respostas

4

Você pode usar o programa awk assim:

awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file

o núcleo é usar a função strftime para converter a data em formato de data

Aqui está a saída:

#awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file
Sun Jan 22 10:12:26 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 2006|179485|121.13.128.132|1409

P.S. Ou você pode usar o delimitador de saída implícito:

awk  'BEGIN { OFS="|"} {$1= strftime("%c",$1) }1' file
    
por 23.05.2017 / 09:35
1

Ou com o seu shell:

while read timestamp pid ip port; do
  echo "$(date -d @$timestamp)|$pid|$ip|$port"
done <yourfile
    
por 23.05.2017 / 09:38
1

Usando o que você já sabe:

  • O GNU date pode converter um registro de data e hora em uma data formatada, fornecendo @timestamp .
  • A substituição de espaços por | fornecerá a saída desejada.

Para isso, adicionamos

  • O GNU date pode operar em um arquivo, convertendo datas em um lote.

Para converter em lote datas com o GNU date , temos que extrair os registros de tempo e prefixá-los com @ :

$ sed 's/^\([^ ]*\).*$/@/' data.in
@1137921146.499
@1137921158.698
@1137921758.163
@1137921802.016

A expressão sed substitui cada linha pelo primeiro campo delimitado por espaço, prefixado com @ .

Com bash (e ksh93 , ou qualquer shell que entenda substituições de processos):

$ date -f <( sed 's/^\([^ ]*\).*$/@/' data.in )
Sun Jan 22 10:12:26 CET 2006
Sun Jan 22 10:12:38 CET 2006
Sun Jan 22 10:22:38 CET 2006
Sun Jan 22 10:23:22 CET 2006

Em seguida, precisamos pegar os outros campos dos dados de entrada e substituir os delimitadores:

$ cut -d ' ' -f 2- data.in | tr ' ' '|'
180900|61.153.158.197|1409
181622|61.153.158.197|1409
180026|221.226.124.114|1374
179485|121.13.128.132|1409

Em seguida, colamos essas duas coisas juntas com um | como delimitador:

$ paste -d '|' <( date -f <( sed 's/^\([^ ]*\).*$/@/' data.in ) ) <( cut -d ' ' -f 2- data.in | tr ' ' '|' )
Sun Jan 22 10:12:26 CET 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 CET 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 CET 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 CET 2006|179485|121.13.128.132|1409
    
por 23.05.2017 / 09:55