tr: chuyển đổi dấu nháy đơn sang ASCII


11

Tôi đang cố gắng chuyển đổi Dấu ngoặc đơn bên phải sang Dấu nháy đơn bằng cách sử dụng tr.

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

đưa ra một tệp được mã hóa UTF-8 có tên aví dụ này:

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

OS X sử dụng BSD trvà tạo ra một kết quả tốt đẹp:

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

Ubuntu sử dụng GNU trvà tạo ra kết quả khó chịu này:

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

Làm cách nào tôi có thể thực hiện chuyển đổi này trong Ubuntu?


Cũng đã thử: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a> b với kết quả tương tự.
plamtrue

1
Điều này là tốt để biết dấu ngoặc kép ASCII và Unicode
aғsнι

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

Câu trả lời:


16

Bạn có thể thử một số công cụ khác, như sed:

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

Hoặc, vì chúng tôi đang thực hiện dịch đơn giản, hãy sử dụng ylệnh cho sed:

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

GNUtr không hoạt động có lẽ vì:

Hiện tại trchỉ hỗ trợ đầy đủ các ký tự byte đơn. Cuối cùng, nó sẽ hỗ trợ các nhân vật đa nhân; khi có, -C tùy chọn sẽ khiến nó bổ sung cho bộ ký tự, trong khi đó -c sẽ khiến nó bổ sung cho bộ giá trị. Sự khác biệt này sẽ chỉ quan trọng khi một số giá trị không phải là ký tự và điều này chỉ có thể xảy ra ở các địa phương sử dụng mã hóa đa bào khi đầu vào chứa lỗi mã hóa.

là một nhân vật đa bào:

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

1
sedlà tốt hơn nhiều cho loại công việc này.
Kaz Wolfe

2
Để giải thích thêm về phần cuối: trthay thế từng ba byte một cách riêng biệt ', do đó '''cũng như các chuỗi bị hỏng trong đó nó đã thay thế hai trong ba byte trong các ký tự tương tự . Thay vào đó, nên hiểu ba byte là cùng một nghĩa và thay thế nó.
deltab

Để hiểu rõ là một ký tự đa dòng, chúng ta cũng có thể sử dụng tr -c '[:print:][:cntrl:]' '-'lệnh để thay thế mọi ký tự không in , trừ các ký tự điều khiển hợp lệ, bằng a -. Và bạn sẽ thấy một bản dịch thành 3 byte ký tự như thế nào ---. điểm tốt cho ký tự nhiều byte.
αsнι

9

Nếu bạn cũng muốn chuyển đổi dấu ngoặc kép và có lẽ các ký tự khác, bạn có thể sử dụng GNUiconv :

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

Các //TRANSLIThậu tố nói iconvrằng cho các ký tự bên ngoài các tiết mục của bảng mã đích (ở đây ASCII), nó có thể thay thế ký tự tương tự hoặc chuỗi tự động. Nếu không có hậu tố, iconvsẽ bỏ cuộc ngay khi tìm thấy một ký tự không thể dịch được.

Lưu ý rằng //TRANSLITdường như là một phần mở rộng GNU: POSIXiconv không hỗ trợ nó.


+1. Nếu bạn đang chuyển đổi một văn bản từ một bộ ký tự (hoặc mã hóa) sang một ký tự khác, có thể sử dụng một công cụ được thiết kế cho mục đích đó.
RedGrittyBrick

@deltab giải pháp của bạn cũng thay thế dấu ngoặc kép mà OP không muốn thay thế chúng.
αsнι

@KasiyA Có lẽ họ nên.
gerrit

3

Bạn có thể sử dụng một trong những awkgiải pháp sau:

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

Hoặc là

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

0

Sử dụng -stùy chọn của tr :

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

Từ man tr :

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

1
giải pháp của bạn cũng thay thế dấu ngoặc kép mà OP không muốn thay thế chúng
αғsнι

Ah, thực sự, cảm ơn vì đã chỉ ra điều này. Tôi sẽ để lại câu trả lời này để tham khảo.
Skippy le Grand Gourou
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.