2017-02-20 2 views
1

Ich versuche, keine nicht-alphanumerischen Zeichen, die in dem ersten Teil zu ersetzen, (vor dem = Vorzeichen) ein Bündel von Schlüsselwertpaaren von einem _:Ersetzen nicht-alphanumerische Zeichen in Teilzeichen

Eingang

aa:cc:dd=foo-bar|17657V70YPQOV 
ee-ff/gg=barFOO 

gewünschte Ausgabe

aa_cc_dd=foo-bar|17657V70YPQOV 
ee_ff_gg=barFOO 

Ich habe versucht, Muster wie: s/\([^a-zA-Z]*\)=\(.*\)/\1=\2/g ohne viel Erfolg. Alle grundlegenden GNU/Linux-Tools können wahrscheinlich verwendet werden.

Antwort

2

Mit awk

$ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
aa_cc_dd=foo-bar|17657V70YPQOV 
ee_ff_gg=barFOO 

Ein- und Ausgangsfeldtrenn werden auf = und dann gsub("[^a-zA-Z]", "_", $1) wird alle nicht-alphabetische Zeichen mit _ nur für die erste Feld substituiert


mit perl

$ perl -pe 's/^[^=]+/$&=~s|[^a-z]|_|gir/e' ip.txt 
aa_cc_dd=foo-bar|17657V70YPQOV 
ee_ff_gg=barFOO 
  • ^[^=]+ non = Zeichen vom Anfang der Zeile
  • $&=~s|[^a-z]|_|gir mit _ nicht-alphabetischen Zeichen ersetzen nur für den angepaßten Teil
  • Verwenden perl -i -pe für inplace Bearbeitung
1

Angenommen, Ihre Eingabe in einer Datei infile genannt wird, könnten Sie dies tun:

while IFS== read key value; do 
    printf '%s=%s\n' "${key//[![:alnum:]]/_}" "${value}" 
done < infile 

mit dem Ausgang

aa_cc_dd=foo-bar|17657V70YPQOV 
ee_ff_gg=barFOO 

Dies setzt die IFS Variable = und liest Ihre Schlüssel/Wert-Paare Zeile für Zeile in eine key und eine value Variable.

Der Befehl printf druckt sie und fügt die = zurück; "${key//[![:alnum:]]/_}" ersetzt alle nicht alphanumerischen Zeichen in key durch einen Unterstrich.

1

Jeden Posix konform awk

$ cat f 
aa:cc:dd=foo-bar|17657V70YPQOV 
ee-ff/gg=barFOO 

$ awk 'BEGIN{FS=OFS="="}gsub(/[^[:alnum:]]/,"_",$1)+1' f 
aa_cc_dd=foo-bar|17657V70YPQOV 
ee_ff_gg=barFOO 

Erläuterung

BEGIN{FS=OFS="="} Set Eingangs- und Ausgangsfeldtrenn =

/[^[:alnum:]]/ Spiel ein Zeichen, das nicht in der Liste enthält, [:alnum:] entspricht ein alphanumerisches Zeichen [a-zA-Z0-9]

gsub(REGEXP, REPLACEMENT, TARGET) Dies ist vergleichbar mit der sub Funktion, außer gsub ersetzt alle der längsten, am weitesten links, nicht überlappend passend Teilstrings kann es finden. Die g in gsub steht für global, die überall bedeutet ersetzen, die gsub Funktion gibt die Anzahl von Substitutionen

gemacht

+1 Es kümmert sich um Standardoperation {print $0}, wenn gsub 0

0

Gedanke kehrt würde ich werfen kleiner Rubin:

ruby -pe '$_.sub!(/[^=]+/){|m| m.gsub(/[^[:alnum:]]/,"_")}'