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

相關內容