tr: kesme işaretini ASCII'ye dönüştür


11

Kullanarak bir kesme işareti sağ tek tırnak işareti dönüştürmek için çalışıyorum .tr

tr "`echo -e '\xE2\x80\x99'`" "`echo -e '\x27'`" < a > b

abu örneği içeren UTF-8 kodlu bir dosya verildiğinde :

Were not a different species
All alone?” Jeth mentioned.

OS X BSD'yi kullanır trve hoş bir sonuç verir:

We're not a different species
“All alone?” Jeth mentioned.

Ubuntu GNU kullanır trve bu kötü sonucu üretir:

We'''re not a different species
''<9C>All alone?''<9D> Jeth mentioned.

Ubuntu'da bu dönüşümü nasıl gerçekleştirebilirim?


Ayrıca denendi: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a> b aynı sonuçlarla.
2014'te


2
echo It’s easy | perl -CS -Mutf8 -pe "tr/’/'/"
tchrist

Yanıtlar:


16

Aşağıdaki gibi başka bir araç deneyebilirsiniz sed:

$ sed "s/’/'/g" <a
We're not a different species
“All alone?” Jeth mentioned.

Veya basit çeviri yaptığımız için şu ykomutu kullanın sed:

$ sed "y/’/'/" <a
We're not a different species
“All alone?” Jeth mentioned.

GNUtr muhtemelen çalışmıyor çünkü:

Şu anda tryalnızca tek baytlık karakterleri tam olarak desteklemektedir. Sonunda çok baytlı karakterleri destekleyecek; bu durumda, -C seçenek karakter kümesini tamamlamasına -c neden olurken , değer kümesini tamamlamasına neden olur. Bu ayrım yalnızca bazı değerler karakter olmadığında önemlidir ve bu yalnızca girdi kodlama hataları içerdiğinde çok baytlı kodlamaları kullanan yerel ayarlarda mümkündür.

Ve çokbaytlı bir karakterdir:

$ echo -n \' | wc -c
1
$ echo -n  | wc -c  
3

1
sedbu tür işler için çok daha hoştur.
Kaz Wolfe

2
Son kısmı daha fazla açıklamak için: trüç baytın her birini ayrı ayrı ', dolayısıyla '''benzer karakterlerde üç bayttan ikisinin yerini aldığı kırık dizilerle değiştirmektir ve . Bunun yerine üç baytı birlikte bir karakter anlamına gelecek şekilde anlamalı ve onun yerine değiştirmelidir.
deltab

İyi anlamak için çok baytlı bir karakterdir, aynı zamanda geçerli kontrol karakterleri hariç, yazdırılmayantr -c '[:print:][:cntrl:]' '-' her karakteri bir ile değiştirmek için komutu kullanabiliriz -. Ve 3 karakterlik baytlara tek bir çeviri göreceksiniz ---. çok baytlı karakter için iyi bir nokta.
αғsнιη

9

Ayrıca çift tırnak işaretlerini ve belki de diğer karakterleri dönüştürmek istiyorsanız GNUiconv kullanabilirsiniz :

$ iconv -f utf-8 -t ascii//translit < a
We're not a different species
"All alone?" Jeth mentioned.

//TRANSLITSoneki söyler iconvhedef kodlaması (burada ASCII) repertuarı dışında karakterler için, otomatik olarak benzer görünümlü karakterler veya dizileri yerini tutabilir. Sonek olmadan, iconvçevrilemez bir karakter bulur bulmaz pes edecek.

Not //TRANSLITgörünüyor bir GNU olmak: POSIXiconv bunu desteklemez.


+1. Bir metni bir karakter kümesinden (veya kodlamadan) diğerine dönüştürüyorsanız, bu amaçla tasarlanmış bir araç kullanmak mantıklı olabilir.
RedGrittyBrick

@deltab çözümünüz, OP'nin değiştirmek istemediği çift tırnak işaretlerinin de yerini alır.
αғsнιη

@KasiyA Belki de yapmalılar.
gerrit

3

Aşağıdaki awkçözümlerden birini kullanabilirsiniz :

awk '{gsub(/\xE2\x80\x99/, "\x27");print}' file # with Hex ASCII code

awk '{gsub(/’/, "\x27");print}' file

awk '{gsub(/\342\200\231/, "\47");print}'  file # with Octal ASCII code

awk '{gsub(/’/, "\47");print}' file

Veya

awk '{gsub(/’/, "'"'"'");print}' file

0

Aşağıdaki -sseçeneklerden birini kullanın tr :

$ echo "We’re not a different species"|tr -s "’" "'"
We're not a different species

Gönderen man tr :

--truncate-set1
          first truncate SET1 to length of SET2

1
çözümünüz aynı zamanda OP'nin değiştirmek istemediği çift tırnak işaretlerinin yerini alır
αғsнιη

Ah, gerçekten, bunu işaret ettiğiniz için teşekkürler. Bu cevabı referans olarak bırakacağım.
Skippy le Grand Gourou
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.