Làm cách nào để chuyển đổi các tệp txt UTF-8 sang tất cả chữ hoa trong bash?


10

Tôi có một số tệp UTF-8 .txt mà tôi muốn chuyển đổi thành tất cả chữ hoa. Nếu đó chỉ là ASCII, tôi có thể sử dụng:

tr [:lower:] [:upper:]

Nhưng vì tôi đang làm việc với các dấu phụ và công cụ, nên nó dường như không hoạt động. Tôi đoán nó có thể hoạt động nếu tôi đặt ngôn ngữ phù hợp, nhưng tôi cần tập lệnh này có thể mang theo được.

Câu trả lời:


14

Tất cả:

tr '[:lower:]' '[:upper:]'

(đừng quên có dấu ngoặc kép, nếu không sẽ không làm việc nếu có một tập tin gọi là :, l... hoặc rtrong thư mục hiện hành) hoặc:

awk '{print toupper($0)}'

hoặc là:

dd conv=ucase

có nghĩa là để chuyển đổi các ký tự thành chữ hoa theo các quy tắc được xác định trong ngôn ngữ hiện tại. Tuy nhiên, ngay cả khi các địa phương sử dụng UTF-8 làm bộ ký tự và xác định rõ ràng việc chuyển đổi từ chữ thường sang chữ hoa, ít nhất là GNU dd, GNU trmawk( awkví dụ trên Ubuntu chẳng hạn) không tuân theo chúng. Ngoài ra, không có cách tiêu chuẩn nào để chỉ định các địa điểm khác ngoài Choặc POSIX, vì vậy nếu bạn muốn chuyển đổi các tệp UTF-8 thành chữ hoa bất kể địa điểm hiện tại, bạn sẽ không gặp may với công cụ tiêu chuẩn.

Như thường lệ, đối với tính di động, đặt cược tốt nhất của bạn có thể là perl:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

Bây giờ, bạn cần cẩn thận rằng không phải ai cũng đồng ý về phiên bản chữ hoa của một ký tự cụ thể là gì.

Chẳng hạn, ở các địa phương Thổ Nhĩ Kỳ, chữ hoa ikhông phải I, nhưng İ( <U0130>). Ở đây với công cụ gia truyền trthay vì GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
İÍ

Trên hệ thống của tôi, perlchuyển đổi từ trên xuống được xác định /usr/share/perl/5.14/unicore/To/Upper.plvà tôi thấy rằng nó hoạt động khác nhau trên một vài ký tự từ GNU libc toupper()trong C.UTF8miền địa phương, perlchính xác hơn. Ví dụ perlmột cách chính xác cải ɀ để Ɀ , các libc GNU (2.17) thì không.


Về giá trị của nó, tôi đang làm việc với các chữ cái tiếng Séc (và ví dụ bạn sử dụng là tiếng Slovak), trong đó tất cả các chữ cái viết hoa được xác định rõ ràng, nhưng bộ ngôn ngữ có thể sẽ là C và không phải là tiếng Séc nên đó là một vấn đề. Perl đã được sử dụng trong chuỗi công cụ này, vì vậy việc thêm một mục đích sử dụng khác có thể không quá tệ. Cảm ơn đã giải thích chi tiết, btw!
VPeric

3

Tôi nghĩ bạn có thể làm điều này với awktoupperchức năng của nó .

Ví dụ

Không hoạt động với GNU tr:

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

Hoạt động với GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ

@StephaneChazelas - cảm ơn tôi đã thay đổi ví dụ thất bại.
slm

Điều đó phụ thuộc vào địa phương hiện tại và vào trhoặc awkthực hiện. Chẳng hạn, hầu hết trsẽ chuyển đổi chính xác ký tự khi ở miền địa phương UTF8, theo miền địa phương hiện tại, GNU trkhông. mawkkhông.
Stéphane Chazelas

1
Trên thực tế, trên FreeBSD (9.1), nó ngược lại. Nó hoạt động với tr, nhưng không phải vớiawk
Stéphane Chazelas

@StephaneChazelas - Tôi không rành về phương sai 8-). Có người chỉ bị hạ bệ, tự hỏi tại sao?
slm

2

Điều này hoạt động với OS X trnhưng không phải với GNU tr:

tr '[:lower:]' '[:upper:]'

Điều này hoạt động với gawknhưng không có mawkhoặc nawk( /usr/bin/awktrong OS X):

awk '{print toupper($0)}'

Một tùy chọn khác là sử dụng GNU sed:

sed 's/./\u&/g'

Trong Bash 4.0 trở lên, bạn cũng có thể sử dụng ^^mở rộng tham số:

while IFS= read -r l;do printf %s\\n "${l^^}";done
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.