2017-07-12 9 views
2

Gibt es eine Möglichkeit, die Ausgabe eines awk-Skripts in eine vorhandene Datei als ein neues Feld jedes Mal zu drucken?Awk: Ausgabe an neues Feld in existierender Datei anhängen

Hallo! Ich bin sehr neu in awk (so meine Terminologie möglicherweise nicht korrekt, tut mir leid, dass!) Und ich versuche, die Ausgabe eines Skripts, das auf mehrere hundert Dateien auf die gleiche Datei in verschiedenen Feldern arbeiten wird.

Zum Beispiel haben meine Datendateien diese Struktur:

#File1 
1 
Values, 2, Hanna 
20 
15 
Values, 2, Josh 
30 
56 
Values, 2, Anna 
50 
70 

#File2 
2 
Values, 2, Hanna 
45 
60 
Values, 2, Josh 
98 
63 
Values, 2, Anna 
10 
56 

Ich habe mehrere dieser Dateien, die durch nummerierte Monat unterteilt sind, mit den gleichen Namen, aber unterschiedliche Werte. Ich möchte Dateien, die mit dem Namen der Person genannt werden, und die Werte in den Feldern für Monat, etwa so:

#Hanna 
20 45 
15 60 

#Josh 
30 98 
56 63 

#Anna 
50 10 
70 56 

In meinem Skript, ich suche nach dem Wort „Werte“, und bestimmen, welche zu drucken aufzeichnet (basierend auf der Zahl nach "Wert"). Das funktioniert gut. Dann möchte ich diese Werte drucken. Es funktioniert für eine Datei in Ordnung, mit dem Befehl:

Print $0 > name #The varible Namen I = $ 3 der richtigen Zeile gespeichert werden

Diese „Hanna“, „Josh“ richtig benannt drei Dateien erstellt und " Anna ", mit ihren Werten. Ich möchte jedoch das Skript für alle meine Datendateien ausführen und sie nur an eine "Hanna" -Datei usw. in einem neuen Feld anhängen.

Also, was ich suche, ist so etwas wie print $0 > $month name, Auslesen wie „den Eintrag im Feld Druck auf den Monat entsprechenden“

habe ich versucht, eine Lösung zu finden, aber die meisten Lösungen entweder nur vorübergehend einfügen Dateien zusammenfassen oder die Werte nach den vorhandenen anhängen (so dass sie alle in Feld 1 sind). Ich möchte die temporären Dateien vermeiden und habe sie in verschiedenen Feldern (damit ich eine Art Matrix-Struktur bekomme).

Vielen Dank im Voraus!

Antwort

0

versuchen Sie folgendes, obwohl ich nicht alle Permutationen und Kombinationen überprüft und nur Ihren Beitrag berücksichtigt. Auch Ihre Josh-Spalte ist nicht konsistent (Oder lassen Sie es uns bitte wissen, wenn für Sie auch andere Bedingungen gelten). Lass mich wissen wie es dann geht.

awk 'FNR==NR{if($0 ~ /^Values/){Q=$NF;B[$NF]=$NF;i="";next};A[Q,++i]=$0;next} /^Values/{V=$NF;print "#"B[V];i="";next} B[V]{print A[V,++i],$0}' file1 file2 

EDIT: Hinzufügen eines nicht-einzeiler Form zu der Lösung.

awk 'FNR==NR{ 
       if($0 ~ /^Values/){ 
             Q=$NF; 
             B[$NF]=$NF; 
             i=""; 
             next 
            }; 
       A[Q,++i]=$0; 
       next 
      } 
    /^Values/{ 
       V=$NF; 
       print "#"B[V]; 
       i=""; 
       next 
       } 
    B[V]{ 
       print A[V,++i],$0 
     } 
    ' file1 file2 

EDIT2: Erklärung Hinzufügen zu jetzt gleich.

awk 'FNR==NR{          ###Checking condition FNR==NR where this condition will be TRUE only when first file named file1 is being read. FNR and NR both indicate number of lines in a Input_file, only difference between them is FNR value will be RESET whenever there is next Input_file is being read and NR value will be keep on incresing till all the Input_files are read. 
       if($0 ~ /^Values/){    ###Checking here if any line starts from string Values if yes then perform following operations. 
             Q=$NF;  ###Creating a variable named Q whose value is the last field of the line. 
             B[$NF]=$NF;###Creating an array named B whose index is $NF(last field of the line) and value is same too. 
             i="";  ###Making variable i value to NULL now. 
             next  ###using next here, it is built-in keyword for awk and it will skip all further statements now. 
            }; 
       A[Q,++i]=$0;      ###Creating an array named A whose index is Q and variable i with increasing value with 1 to it, each time it comes on this statement. 
       next        ###Using next will skip all further statements now. 
      } 
    /^Values/{         ###All statements from here will be executed when second file named file2 is being read. So I am checking here if a line starts from string Values then do following. 
       V=$NF;        ###create variable V whose value is $NF of current line. 
       print "#"B[V];      ###printing the string # then value of array B whose index is variable V. 
       i="";        ###Nullifying the variable i value here. 
       next        ###next will sip all the further statements now. 
       } 
    B[V]{           ###Checking here if array B with index V is having a value in it, then perform following on it too. 
       print A[V,++i],$0     ###printing the value of array A whose index is variable V and variable i increasing value with 1 and current line. 
     } 
    ' file1 file2         ###Mentioning the Input_files here named file1 and file2. 
+0

Vielen Dank für Ihre Antwort! Ich korrigierte den obigen Josh-Tippo. Da ich awk jedoch sehr neu bin, verstehe ich nicht wirklich, wie man seine Lösung implementiert? Ich schreibe es in eine txt-Datei mit der Syntax BEGIN {....} und führe es durch Schreiben von awk -f script.txt data1.data vom Terminal aus. Soll ich deinen Code in meine TXT-Datei oder in das Terminal schreiben? Tut mir leid, dass ich nicht mehr weiß, ich dachte, das könnte durch eine einfache Kombination von '>' und '$' gelöst werden: P Tut mir leid, dass ich Ihnen so viele Probleme gemacht habe. –

+0

Cool, ich habe jetzt auch eine Erklärung hinzugefügt, weiter lernen, teilen :) EDIT: Du könntest es auch am Terminal ausführen, du könntest ein BASH-Skript erstellen und daraus auch laufen und ja könntest du es auch von awk -f ausführen machen Sie kleine Änderungen, lassen Sie mich wissen, wie es für Sie geht – RavinderSingh13

+0

Wow, so das (Art von) funktioniert! (und machte den Rest meines Codes überflüssig, haha). Vielen Dank! Jedoch, und ich sehe jetzt, dass das ein bisschen unklar war. Ich möchte, dass die Ausgaben nach den Namen in drei verschiedenen Dateien gespeichert werden. Also sollte die Datei mit dem Titel "Anna" Annas vier Zahlen enthalten, eine Datei "Josh" mit Joshs Zahlen usw. Wo könnte ich das umsetzen? In meinem ursprünglichen Code hatte ich gerade [> name] am Ende der Sequenz, aber jetzt speichert es alle Werte zu Anna. –