
У меня есть файл, содержимое которого примерно такое:
Файл .txt:
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Я хочу разделить этот один файл на несколько файлов на основе начальной строки "661" и даты (2016MMDD) и переименовать разделенный файл в 20160315.txt, 20160316.txt и т. д. Например, каждый разделенный файл будет иметь:
20160315.txt будет иметь:
661###############20160315########
################################
################################
20160316.txt будет иметь:
661###############20160316########
################################
20160317.txt будет иметь:
661###############20160317#######
###############################
Есть ли команда awk, которая может это сделать?
решение1
Я уверен, что есть awk
команда, которая может это сделать, я не настолько опытен, чтобы awk
придумать решение. В то же время, вы можете использовать что-то вроде этого:
#!/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*
Где tosplit
находится этот файл (ваш пример файла):
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
После запуска этого скрипта (в том же каталоге, что и tosplit
файл) я получаю три файла:
ls 2016031*
20160315.txt 20160316.txt 20160317.txt
...выглядит примерно так:
cat 20160315.txt
661###############20160315###
###########################
###########################
cat 20160316.txt
661###############20160316###
###########################
cat 20160317.txt
661###############20160317###
###########################
Вы, возможно(?), csplit
также можете использовать его для именования файлов, но это тоже выше моих сил!
решение2
С awk
чем-то вроде
awk '/^661/{f=substr($0,match($0,/2016[0-9]{4}/),8)".txt"}{print>>f}' file.txt
может подойти вам.
В основном это следующие части:
/^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
При традиционной awk
реализации вам, возможно, придется заменитьинтервальные выраженияк:
awk '/^661/{f=substr($0,match($0,/2016[01][0-9][0-9][0-9]/),8)".txt"}{print>>f}' file.txt
В зависимости от вашего варианта использования вы также можете захотеть изменитьповедение перенаправления, т.е. print>f
против print>>f
.