2016-04-01 22 views
1

In den folgenden Daten, ich möchte alle Kommas ersetzen, die nicht sofort gefolgt werden von Leerzeichen mit ~. So würde das Komma in "American President, The (1995)" bestehen bleiben, da es unmittelbar danach Whitespace gibt.Finden Sie zwei Zeichenmuster, ersetzen Sie nur ein Zeichen

10,GoldenEye (1995),Action|Adventure|Thriller 
11,"American President, The (1995)",Comedy|Drama|Romance 

Hier ist der Ausgang Ich möchte:

10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance 

ich den Code unten habe versucht, aber das ersetzt zwei Zeichen, anstatt nur die erste.

sed 's/,[^ ]/~/g' file.csv 

Der Ausgang I ist unten erhalten:

10~oldenEye (1995)~ction|Adventure|Thriller 
11~American President, The (1995)"~omedy|Drama|Romance 

Antwort

0

Erste gsub ersetzt die Kommas in der ersten Zeile und die folgenden zwei Unter ändert das erste und das letzte Komma in der zweiten Zeile.

awk 'NR<2{gsub(/,/,"~")}{sub(/1,/,"1~")}{sub(/,C/,"~C")}1' file 
10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance 
0

Versuchen sed 's/,\([^ \t]\)/~\1/g' file.csv
Dies gibt Ihnen die gewünschte Leistung.
Beachten Sie, dass dies kein nachkommendes Komma ersetzt, also ist es technisch gesehen nur eine Teillösung.
Ich weiß sed kann genau das tun, was Sie gefragt haben, aber ich weiß nicht wie.
Wenn Sie nachträgliche Kommas sowieso nicht konvertieren müssen, ist das egal.

Was dies tut, ist ,[^ \t], die ein Komma gefolgt von einem Zeichen, das kein Leerzeichen oder eine Registerkarte ist. Die '\( und \) können verwendet werden, um sich daran zu erinnern, was abgeglichen wurde, und dann kann der Wert, der durch den ersten Satz von '\(...\) erreicht wurde, als \1 referenziert werden. Der zweite Satz kann als \ 2 usw.

0

Diese verwiesen werden könnte für Sie arbeiten (GNU sed):

sed -r ':a;s/,(\S|$)/~\1/g;ta' file 

Diese alle von einem Nicht-Leerzeichen oder der Ende- gefolgt , ‚s ersetzt der Datei

N.B. die Substitution in zwei möglichen Pässe zu benachbarten , ‚s

0

Das funktioniert, wenn Sie nie haben zwei aufeinander folgende Kommas enthalten:

$ sed -r 's/,([^[:blank:]]|$)/~\1/g' file 
10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance 

oder:

$ awk '{$0=gensub(/,(\S|$)/,"~\\1","g")}1' file 
10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance 

Wenn Sie mehrere aufeinanderfolgende haben Kommas dann bleibe ich bei awk:

$ awk '{ while($0!=($0=gensub(/,(\S|$)/,"~\\1","g"))); }1' file 
10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance 

Hier ist was passiert w ith beide Ansätze, wenn/wenn Sie aufeinander folgende Kommas haben:

$ echo 'a,,b' | sed -r 's/,([^[:blank:]]|$)/~\1/g' 
a~,b 

$ echo 'a,,b' | awk '{$0=gensub(/,(\S|$)/,"~\\1","g")}1' 
a~,b 

$ echo 'a,,b' | awk '{ while($0!=($0=gensub(/,(\S|$)/,"~\\1","g"))); }1' 
a~~b 

Die oben verwendet GNU awk für gensub() so auch \S statt [^[:blank]] I verwendet, da die Lösung GNU erfordert awk so auch \S mit sich selbst nicht Portabilität opfern. Wenn Sie GNU sed verwenden, unterstützt es auch \S anstelle von [^[:blank:]], idk über andere seds.Mit anderen awks würde es sein:

awk '{ while(i=match($0,/,([^[:blank:]]|$)/)) $0=substr($0,1,i-1)"~"substr($0,i+1) } 1' 
Verwandte Themen