Aufteilen einer einzelnen Datei in mehrere Dateien basierend auf übereinstimmenden Zeichenfolgen in Linux

Aufteilen einer einzelnen Datei in mehrere Dateien basierend auf übereinstimmenden Zeichenfolgen in Linux

Ich habe eine Datei mit ungefähr folgendem Inhalt:

Datei.txt:

661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################

Ich möchte diese einzelne Datei basierend auf der Startzeichenfolge „661“ und dem Datum (2016MMDD) in mehrere Dateien aufteilen und die geteilte Datei in 20160315.txt, 20160316.txt usw. umbenennen. Jede geteilte Datei enthält beispielsweise:

20160315.txt enthält:

661###############20160315########
################################
################################

20160316.txt enthält:

661###############20160316########
################################

20160317.txt enthält:

661###############20160317#######
###############################

Gibt es einen Awk-Befehl, der das kann?

Antwort1

Ich bin sicher, dass es einen awkBefehl gibt, der das kann, aber ich bin nicht erfahren genug, um awkeine Lösung zu finden. In der Zwischenzeit könnten Sie so etwas verwenden:

#!/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*

Wo tosplitist diese Datei (Ihre Beispieldatei):

661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################

Nach dem Ausführen dieses Skripts (im selben Verzeichnis wie die tosplitDatei) erhalte ich drei Dateien:

ls 2016031*
20160315.txt  20160316.txt  20160317.txt

...sieht so aus:

cat 20160315.txt 
661###############20160315###
###########################
###########################

cat 20160316.txt 
661###############20160316###
###########################

cat 20160317.txt 
661###############20160317###
###########################

Sie können möglicherweise(?) csplitauch zur Benennung der Dateien verwenden, aber auch das übersteigt meine Kompetenz!

Antwort2

Mit awkso etwas wie

awk '/^661/{f=substr($0,match($0,/2016[0-9]{4}/),8)".txt"}{print>>f}' file.txt

könnte für Sie funktionieren.

Im Wesentlichen sind die Teile:

/^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

Bei einer herkömmlichen awkImplementierung müssen Sie möglicherweise dieIntervallausdrückeZu:

awk '/^661/{f=substr($0,match($0,/2016[01][0-9][0-9][0-9]/),8)".txt"}{print>>f}' file.txt

Abhängig von Ihrem Anwendungsfall möchten Sie möglicherweise auch dieVerhalten der Umleitung, also print>fvs. print>>f.

verwandte Informationen