Linux中根据匹配字符串将单个文件拆分为多个文件

Linux中根据匹配字符串将单个文件拆分为多个文件

我有一个文件,其内容如下:

文件.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>fvs. print>>f

相关内容