2016-04-15 6 views
-1

Ich versuche, eine Zeile zu ersetzen ersetzt gegebene Kontexte auf zwei Seiten eines Split. Dies scheint viel einfacher, in Python zu tun, aber meine gesamte Pipeline ist in bash so würde ich gerne zu Tools wie sed, awk, grep-Stick usw.Zeile ersetzt gegebene Kontexte auf zwei Seiten eines Splits

Zum Beispiel:

split_0 = split('\t')[0] 
split_1 = split('\t')[1] 
if (a b c in split_0 AND w x y z in split_1): 
    split_1 = split_1.replace('w x y z', 'w x_y z') 

I awk verwenden können zu tun Splits wie folgt aus:

awk -F '\t' '{print$1}' 

Aber ich weiß nicht, wie diese, um beide Bedingungen zu erfüllen gleichzeitig auf beiden Seiten zu tun. Jede Hilfe würde sehr geschätzt werden.

Beispiel Eingabe/Ausgabe: Dies ist ein Beispiel und ich habe viele Regeln wie diese, aber im Grunde, was ich hier tun möchte, wird ein Beispiel gegeben, wo ich "ex" auf der linken Seite und "ih gz" auf der rechte Seite, ich möchte eine Ersetzung mit ih gz zu ih g_z machen.

input: exam ih g z ae m 
output: exam ih g_z ae m 

Ich konnte eine brutale tun sed wie:

sed 's/\(.*ex.*\t.*\)ih g z\(.*\)/\1ih g_z\2/g' 

aber dies scheint hässlich, und ich bin sicher, dass es eine viel bessere Möglichkeit, dies zu tun ist. * Ich bin mir nicht ganz sicher, ob das "\ t" in sed funktioniert.

+0

Können Sie uns einige Beispiel Eingabe/Ausgabe geben? –

+0

@ Mr Llama, aktualisiert! – badner

+0

@Ed Morton Ich denke, es könnte besser sein, wenn ich das Beispiel besser erklärte. Aber ich denke, die Frage ist ziemlich klar. Dies ist keine einfache Substitution, sondern eine Substitution auf der einen Seite unter gegebenen Bedingungen auf beiden Seiten. – badner

Antwort

1

awk zur Rettung!

Bedingungen für Felder 1 und 2 getrennt durch Tabulatorbegrenzer, ersetzen Zeichenfolge (einmal).

Wenn Sie eine Reihe dieser Ersetzungsregeln haben, ist es besser, nicht schwer, sie im Script-Code

$ awk -F'\t' -v OFS='\t' 'NR==FNR{lr[NR]=$1; rr[NR]=$2; 
             ls[NR]=$3; rs[NR]=$4; next} 
            {for(i=1; i<=length(lr); i++) 
             if($1~lr[i] && $2~rr[i]) 
              {gsub(ls[i],rs[i],$2); 
              print; 
              next}}1' rules file 

111  2b2b2b 
222  333u33u 
4  bbb5az 
9  nochange 

wo

$ head rules file 
==> rules <== 
1  2  a  b 
2  3  z  u 
4  5  e  b 

==> file <== 
111  2a2a2a 
222  333z33z 
4  eee5az 
9  nochange 

, dass der Ersatz Bemerkt wird für die erste anwendbare Regel sein auf zweites Feld nur und mehrmals. Beide Dateien müssen tabulatorgetrennt sein.

+0

Ich mag das. Es ist besser als meine Sed. Aus Neugier, wie kann ich mit awk negieren, kann ich "^" verwenden? Für den Fall, dass ich einen Konflikt habe, als ob ich auf der linken Seite Exs hätte, würde ich es negieren wollen. – badner

+0

oder ist es "! ~"? – badner

+0

'$ 1! ~/Ex /' ist die Negation der Musterübereinstimmung. – karakfa

Verwandte Themen