
Tengo un archivo que tiene un contenido similar a este:
Archivo.txt:
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Quiero dividir este archivo único en varios archivos según la cadena inicial "661" y la fecha (2016MMDD) y cambiar el nombre del archivo dividido a 20160315.txt, 20160316.txt, etc. Por ejemplo, cada archivo dividido tendrá:
20160315.txt tendrá:
661###############20160315########
################################
################################
20160316.txt tendrá:
661###############20160316########
################################
20160317.txt tendrá:
661###############20160317#######
###############################
¿Existe algún comando awk que pueda hacerlo?
Respuesta1
Estoy seguro de que hay un awk
comando que puede hacer esto, no tengo la habilidad suficiente para awk
encontrar una solución. Mientras tanto, podrías usar algo como esto:
#!/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*
¿Dónde tosplit
está este archivo (su archivo de ejemplo)?
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Después de ejecutar este script (en el mismo directorio que el tosplit
archivo), obtengo tres archivos:
ls 2016031*
20160315.txt 20160316.txt 20160317.txt
...luciendo así:
cat 20160315.txt
661###############20160315###
###########################
###########################
cat 20160316.txt
661###############20160316###
###########################
cat 20160317.txt
661###############20160317###
###########################
csplit
Posiblemente (?) también puedas usarlo para nombrar los archivos, ¡pero eso también está por encima de mi nivel de pago!
Respuesta2
con awk
algo como
awk '/^661/{f=substr($0,match($0,/2016[0-9]{4}/),8)".txt"}{print>>f}' file.txt
podría funcionar para usted.
Básicamente las partes son:
/^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
Con una awk
implementación tradicional es posible que tengas que reemplazar elexpresiones de intervaloa:
awk '/^661/{f=substr($0,match($0,/2016[01][0-9][0-9][0-9]/),8)".txt"}{print>>f}' file.txt
Dependiendo de su caso de uso, es posible que también desee cambiar elcomportamiento de la redirección, es decir , print>f
vs.print>>f