
Eu tenho um arquivo que tem conteúdo mais ou menos assim:
Arquivo.txt:
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Quero dividir este único arquivo em vários arquivos com base na string inicial "661" e na data (2016MMDD) e renomear o arquivo dividido como 20160315.txt, 20160316.txt e assim por diante. Por exemplo, cada arquivo dividido terá:
20160315.txt terá:
661###############20160315########
################################
################################
20160316.txt terá:
661###############20160316########
################################
20160317.txt terá:
661###############20160317#######
###############################
Existe um comando awk que pode fazer isso?
Responder1
Tenho certeza de que existe um awk
comando que pode fazer isso, não tenho habilidade suficiente para awk
encontrar uma solução. Enquanto isso, você poderia usar algo assim:
#!/bin/bash
csplit -z tosplit /661/ {*}
for file in xx*; do
newName=$(egrep -o '2[0-9]{7}' $file)
mv $file $newName.txt
done
rm -rf xx*
Onde tosplit
está este arquivo (seu arquivo de exemplo):
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Depois de executar este script (no mesmo diretório do tosplit
arquivo), recebo três arquivos:
ls 2016031*
20160315.txt 20160316.txt 20160317.txt
... assim:
cat 20160315.txt
661###############20160315###
###########################
###########################
cat 20160316.txt
661###############20160316###
###########################
cat 20160317.txt
661###############20160317###
###########################
Você também pode (?) usar csplit
para nomear os arquivos, mas isso também está acima do meu salário!
Responder2
Com awk
algo como
awk '/^661/{f=substr($0,match($0,/2016[0-9]{4}/),8)".txt"}{print>>f}' file.txt
pode funcionar para você.
Basicamente as peças são:
/^661/{...} # on each line starting with 661
match($0,/2016[0-9]{4}/) # find the index of the date (2016MMDD) in current line
substr($0,match($0,/2016[0-9]{4}/),8) # extract the the date in the current line
f=substr($0,match($0,/2016[0-9]{4}/),8)".txt" # assign it to f and append ".txt"
{print>>f} # redirect the content of the current line into the file named by f
Com uma awk
implementação tradicional você pode ter que substituir oexpressões de intervalopara:
awk '/^661/{f=substr($0,match($0,/2016[01][0-9][0-9][0-9]/),8)".txt"}{print>>f}' file.txt
Dependendo do seu caso de uso, você também pode querer alterar ocomportamento do redirecionamento, ou seja , print>f
vs.print>>f