
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 awk
Befehl gibt, der das kann, aber ich bin nicht erfahren genug, um awk
eine 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 tosplit
ist diese Datei (Ihre Beispieldatei):
661###############20160315###
###########################
###########################
661###############20160316###
###########################
661###############20160317###
###########################
Nach dem Ausführen dieses Skripts (im selben Verzeichnis wie die tosplit
Datei) 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(?) csplit
auch zur Benennung der Dateien verwenden, aber auch das übersteigt meine Kompetenz!
Antwort2
Mit awk
so 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 awk
Implementierung 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>f
vs. print>>f
.