2013-01-04 1 views
6

Ich habe eine Reihe von Daten, die wie dieseSuche nach mehreren konditionierten String mit awk

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC6 DEF6 GHI6 cond1 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 
ABCc DEFc GHIc Mcond1 

ein paar Befehle zu schreiben Ich versuche, sieht die Daten zu trennen nach dem „col4“ zu bekommen:

  1. Eine Datei, die die Zeichenfolge "cond1" mit ALLEN davor oder danach enthält, außer für die Buchstaben "M" und "m". Ich bin derzeit mit diesem Befehl (nicht M und m nicht ausschließt, natürlich) dafür:

    awk 'BEGIN{IGNORECASE=1} $4 ~ /.cond1/ || $4 ~ /cond1./ ' /filepath.tab 
    

    bitte auch nicht, dass die 4., 9. und dem 11. Datenzeilen enthält Leerzeichen zwischen „cond1“ und andere Strings, ich möchte dies in der Datei enthalten. (Nicht der „“ in dem Befehl Leerzeichen?)

  2. ich einen Befehl schrieb eine Datei zu erhalten, die ‚cond1‘ nur in dem ‚col4‘

    awk 'BEGIN{IGNORECASE=1} $4 ~ /^cond1$/ ' /filepath.tab 
    

    es enthält funktioniert gut mit dem meisten obwohl die Daten, ich bin immer diese 2 Fehler in den Ergebnissen:

    ABC9 DEF9 GHI9 cond1 at 50 
    ABCc DEFc GHIc cond1 something 
    

Kann jemand bitte helfen Sie mir mit diesen 2 Befehlen? Danke.

ich für eine Leistung von 3 Dateien suchen, die keine Duplikate enthält, hier ein Beispiel: File1 (enthält alle Kombinationen mit cond1):

col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

File2 (mit cond1 allein):

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

File3 (enthält alles, was nicht in file1 und file2 enthalten war):

col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

Beachten Sie, dass die Gesamtzahl der Zeilen der 3 Dateien der Originaldatei entspricht. Es tut mir leid, wenn das ziemlich kompliziert klingt, aber das ist der Fall, den ich tatsächlich habe.

+0

Was ist Ihr Wunsch Ausgabe! –

+0

Was ist der Separator zwischen den Säulen? ist es tab? wenn seine Spalte in der 11. Zeile in der 4. Spalte nicht 'cond1' enthält. Es ist 5. Spalte dort –

+0

Ja, es ist eine Tab-getrennte Datei, und manchmal gibt es einen einzigen Abstand zwischen Wörtern. (und ich bin mir sicher, dass es keine anderen Spalten ist, da dies eine große Datei war und ich Schnitt verwendete, um diese 4 Spalten herauszunehmen) – Error404

Antwort

2

Das Problem ist, dass Spalte 4 Leerzeichen und Ihre Datei formatiert ist nicht so versuchen awk -F'\t' {print $4} file erwartet und feststellen, es ist wahrscheinlich nicht das, was Sie erwarten.

Drehen Sie zuerst die Datei im CSV-Format mit sed

$ sed 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 
col1,col2,col3,col4 
ABC1,DEF1,GHI1,cond1 
ABC2,DEF2,GHI2,cond1-cond2 
ABC3,DEF3,GHI3,cond2/cond1 
ABC4,DEF4,GHI4,cond2 cond1 
ABC5,DEF5,GHI5,cond4/cond1 
ABC6,DEF6,GHI6,cond1 
ABC7,DEF7,GHI7,mcond1 
ABC8,DEF8,GHI8,cond2 
ABC9,DEF9,GHI9,cond1 at 50 
ABCa,DEFa,GHIa,con cond1 
ABCb,DEFb,GHIb,no. cond1 
ABCc,DEFc,GHIc,cond1 something 
ABCc,DEFc,GHIc,Mcond1 

Dies ist nur die ersten 3 Leerzeichen Gruppen Kommas umwandelt verlassen col4 wie Sie wollen. Zum Speichern der Änderung in der Datei, die die -i Option:

sed -i 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 

Nun ist die Feldtrenn , verwendet werden.

awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/cond1./|| $4~/[^mM]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

$ awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/^cond1$/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

$ awk 'BEGIN{FS=",";OFS="\t"} $4!~/cond1/ || $4~/[Mm]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

einfach umleiten die NewFiles awk '{...}' > file1 zu speichern.

+0

Hallo, Danke für deinen Befehl. Für den ersten Befehl (nachdem er in eine kommagetrennte Datei umgewandelt wurde) wurden sogar die Leerzeichen zwischen den Wörtern in Kommas umgewandelt. also habe ich die Felder "cond1 bei 50", "cond1 something", "cond2 cond1", "con cond1" und "no. cond1" verloren. – Error404

+0

@ Error404 nein Der 'sed' Befehl ist so konstruiert, dass nur die ersten 3 Leerzeichen durch Kommas ersetzt werden. Ich habe meine Antwort aktualisiert, um dies zu erklären. –

+0

ja dude, Danke für deine Antwort ... jetzt, da ich den Befehl verstehe, weiß ich, wie man einen Fisch fängt und ich werde jeden Tag essen :) – Error404

1

Da Ihre Felder tabulatorgetrennt sind, verwenden Sie FS="\t" in BEGIN Block. Auch dein Zustand ist nicht korrekt. Also habe ich es geändert.

awk 'BEGIN{IGNORECASE=1; FS="\t"; } $4 ~ /cond1/ && $4 !~ /mcond1|cond1m/' data 
+0

Danke für den Befehl. Eigentlich funktioniert das auf eine gute Weise, aber ich möchte etwas zu diesem Befehl hinzufügen. wenn ich das in col4 "mcond1 cond1" hätte, wenn mcond1 und cond1 gleichzeitig dort sind, möchte ich, dass es eingeschlossen wird, wenn mcond1 alleine oder mit etwas anderem war, dann NEIN. Wie sage ich das? – Error404

+0

Dieser OverMatches enthält Zeile 1 und 6 sowie keine Kopfzeile. –

1

Sie könnten die Aufgabe mit einem einzigen Durchlauf erledigen. Lauf wie:

awk -f script.awk file 

Inhalt von script.awk:

BEGIN { 
    FS="\t" 
} 

NR==1 { 
    r=$0 
    next 
} 

{ 
    i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)) 
    print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" 
} 

Ergebnisse grep . file[1-3].txt:

file1.txt:col1 col2 col3 col4 
file1.txt:ABC2 DEF2 GHI2 cond1-cond2 
file1.txt:ABC3 DEF3 GHI3 cond2/cond1 
file1.txt:ABC4 DEF4 GHI4 cond2 cond1 
file1.txt:ABC5 DEF5 GHI5 cond4/cond1 
file1.txt:ABC9 DEF9 GHI9 cond1 at 50 
file1.txt:ABCa DEFa GHIa con cond1 
file1.txt:ABCb DEFb GHIb no. cond1 
file1.txt:ABCc DEFc GHIc cond1 something 
file2.txt:col1 col2 col3 col4 
file2.txt:ABC1 DEF1 GHI1 cond1 
file2.txt:ABC6 DEF6 GHI6 cond1 
file3.txt:col1 col2 col3 col4 
file3.txt:ABC7 DEF7 GHI7 mcond1 
file3.txt:ABC8 DEF8 GHI8 cond2 
file3.txt:ABCc DEFc GHIc Mcond1 

Alternativ ist hier die Einzeiler:

awk -F "\t" 'NR==1 { r=$0; next } { i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)); print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" }' file