2016-07-14 6 views
0

Hier ist meine Frage. Ich habe mehrere hundert Dateien, die zu groß sind, um mit dem Editor vi zu bearbeiten. Ich suche nach einem möglichen awk oder sed Befehl, um meine Dateien zu manipulieren. Etwas von einem Anfänger. Ich habe eine vereinfachte Datei:Einfügen von Zeichen in bestimmte Felder in großen Dateien

001|1|3|053412|16|1234||| 
001|21|4|123618|15|88||| 

Die Dateien wurden erstellt, mit dem vierten Feld im falschen Format. Das vierte Feld sollte 05:34:12 sein, was HH: MM: SS widerspiegelt. Die Zeitwerte sind korrekt, ich muss nur die : an den entsprechenden Stellen einfügen.

Wie füge ich die Doppelpunkte nach dem zweiten Zeichen und die vierten Zeichen in das vierte Feld ein? Ich kann es nicht durch Zeichenanzahl machen, da die Werte vor und nach dem vierten Feld variabel sind.

+0

sind Felder immer getrennt um eine oder mehrere vertikale Balken ?, Ist die Anzahl der Felder immer gleich? – Firefly

+0

ja das Trennzeichen ist Rohre. Ich habe meine Antwort, danke an alle! –

Antwort

1

gawk zur Rettung!

$ sed -r 's/([^|]*|[^|]*|[^|]*|)([0-9]{2})([0-9]{2})([0-9]{2})/\1\2:\3:\4/' file 
001|1|3|05:34:12|16|1234||| 
001|21|4|12:36:18|15|88||| 
+0

Karakfa ... Ich verneige mich vor dir !!! Sie sind mein Held!!! Danke SO SEHR VIEL .. Du bist ein GOTT !!!!! –

0

Mit sed das gleiche tun!

awk -F"|" -v OFS="|" '{r=split($4,T,"");for(i=2;i<=r;i+=2){if(i!=r)T[i]=T[i]":"}tmp="";for(i=1;i<=r;i++){tmp=tmp T[i]}$4=tmp;}1' file 

001|1|3|05:34:12|16|1234||| 
001|21|4|12:36:18|15|88||| 

Längerer Whit Erklärung:

BEGIN{ 
FS=OFS="|"; #Field separator and output field separator 
} 
{ 
    tmp=""; 
    r=split($4,time_field,""); # Chunk field into pieces 
    for(i=2;i<=r;i+=2) # Loop two by two 
    { 
     if(i!=r) 
     { 
      time_field[i]=time_field[i]":"; # Add ":" 
     } 
    } 

    for(i=1;i<=r;i++) # Loop over again to rebuild 
    { 
     tmp=tmp time_field[i]; 
    } 
    $4=tmp; #rebuid field 
    print 
} 

How you could use it in bash: Save it as whatever.awk 

while IFS='' read -r file 
do 
awk -f whatever.awk "$file" > out_file 
done < list_of_files_to_edit.txt 

Wenn Sie die Dateien an Ort und Stelle bearbeiten möchten, können Sie die Option -i Kenavoz sed Befehl hinzufügen können. -ri sed ...

+0

Schätzen Sie es Kenavoz !! –

0

Versuchen Sie, diese awk:

$ awk -F\| -v OFS=\| '{$4=gensub(/(..)(..)(..)/,"\\1:\\2:\\3","g",$4)}1' file 

001|1|3|05:34:12|16|1234||| 
001|21|4|12:36:18|15|88||| 

sonst kann man mit substr($4,1,2)":"...

+0

Sie sollten erwähnen, dass nur in Awks funktioniert, die Strings in einzelne Zeichen mit einem Nullfeldtrennzeichen (GNU awk Willen, aber es ist undefiniertes Verhalten in POSIX) aufgeteilt. Verwenden Sie beim Schreiben von Shell-Loops immer 'IFS =' und '-r', es sei denn, Sie haben einen bestimmten Zweck, indem Sie dies nicht tun und die Nebenwirkungen vollständig verstehen (siehe [why-is-using-a-shell-loop-to- Prozess-Text-betrachtet-schlechte-Praxis] (http://unix.stackexchange.com/questions/169716/why-isusing-a-shell-loop-to-process-text-considered-bad-practice)) . Sie haben awk Syntax-Probleme - lesen Effektive Awk Programmierung, 4. Ausgabe, von Arnold Robbins –

+0

@EdMorton Ich kann nicht sintax Probleme sehen, können Sie mir ein Beispiel geben? – Firefly

+0

Das erste arg to sub() ist ein Regexp, kein String, also sollten Sie 'sub (/: $ /," ", tmp)', nicht 'sub (": $ "," ", tmp) verwenden '. Die abschließenden Semikolons überlasten den Code. 'print $ 0' sollte nur' print' sein. Ihre Schleifen fügen '' 's hinzu, müssen dann die letzte entfernen, anstatt nur genau das hinzuzufügen, was Sie wollen, und warum zu den Array-Elementen hinzufügen und dann eine Zeichenkette daraus erstellen, anstatt sie nur in einer Schleife zu machen. Oh, und abgesehen von den awk-Sachen musst du alle deine Shell-Variablen zitieren - benutze '" $ file "', nicht '$ file'. –

0

Dies könnte für Sie arbeiten (GNU sed):

sed -r 's/^(([^|]*\|){3})(..)(..)/\1\3:\4:/' file 

Verwenden Sie Verweise auf Gruppe die ersten drei Felder zurück und die folgenden zwei Paare. Formatieren Sie dann das vierte Feld wie gewünscht.

+0

Danke POTONG !!!! –

1

Mit GNU awk für gensub() und Inplace Editing

awk -i inplace 'BEGIN{FS=OFS="|"} {$4=gensub(/(..)(..)/,"\\1:\\2:",1,$4)} 1' * 

Ähnlich ist es mit GNU sed für EREs und Inplace Editing:

sed -i -E 's/(([^|]*\|){3}..)(..)/\1:\3:/' * 

zB:

$ awk 'BEGIN{FS=OFS="|"} {$4=gensub(/(..)(..)/,"\\1:\\2:",1,$4)} 1' file 
001|1|3|05:34:12|16|1234||| 
001|21|4|12:36:18|15|88||| 

$ sed -E 's/(([^|]*\|){3}..)(..)/\1:\3:/' file 
001|1|3|05:34:12|16|1234||| 
001|21|4|12:36:18|15|88||| 
+1

Danke Ed !!!!! –

Verwandte Themen