Làm cách nào để thay thế tất cả các chuỗi UTF-8 được mã hóa phần trăm bằng văn bản UTF-8 đơn giản?


9

Tôi đã có một tệp html có rất nhiều văn bản UTF-8 được mã hóa% trong các URL.

Ví dụ: "% D1% 80% D0% B5% D1% 81% D1% 83% D1% 80% D1% 81% D1% 8B" là viết tắt của "ресурсы" ("tài nguyên" trong tiếng Nga).

Nhiệm vụ là thay thế tất cả các chuỗi con như vậy bằng văn bản UTF-8 có thể đọc được.

Để đơn giản hóa tác vụ chúng ta có thể xem xét không có %cách sử dụng dấu hiệu nào khác trong tệp. Chữ số có thể là cả chữ hoa và chữ thường

Tôi nghi ngờ điều này có thể thực hiện thanh lịch với sed, perl, awkhoặc một cái gì đó nhưng không biết làm thế nào.

Ứng dụng web này dường như thực hiện thủ thuật với văn bản bạn dán ở đó.

Câu trả lời:


9

Với bash, zsh, GNU echo hoặc một số triển khai ksh trên một số hệ thống, điều này có thể được giải mã đơn giản bằng cách echo -ethay thế tất cả %bằng \x.

url_encoded_string="%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B"
temp_string=${url_encoded_string//%/\\x}

printf '%s\n' "$temp_string"
# output: \xD1\x80\xD0\xB5\xD1\x81\xD1\x83\xD1\x80\xD1\x81\xD1\x8B

echo -e "$temp_string"
# output: ресурсы

(Nó giả sử chuỗi không chứa các ký tự dấu gạch chéo ngược và không phải là một trong các tùy chọn được echolệnh của bạn hỗ trợ )

Như @JoshLee cũng chỉ ra, "tiếng vang vọng" có thể tránh được bằng cách sử dụng trực tiếp:

printf ${url_encoded_string//%/\\x}

thay vì trực tiếp đằng sau lệnh đầu tiên.


Lưu ý rằng giải pháp tao nhã này sẽ hoạt động với bất kỳ mã hóa nào , không chỉ UTF-8 (nghĩa là loại bỏ các mã hóa cho ~ và các loại khác. Một mẹo khác để thêm vào hộp công cụ của tôi. Cảm ơn!
vonbrand

5

Với perl:

perl -pe 's/%([0-9A-F]{2})/pack"H2",$1/gei'

Hoặc với URI::Escape:

perl -MURI::Escape -pe '$_=uri_unescape$_'

Tôi thích điều này bởi vì tôi có thể đặt nó bất cứ điều gì tôi muốn nhờ $_ gnu.org/software/bash/manual/html_node/ecial-Parameter.html
Nemo

@Nemo, $_đây là perl's $_, không bash' s. Kết hợp với -ptùy chọn, biểu thức perl được chạy cho mọi bản ghi đầu vào (các bản ghi được đọc từ các tệp được cung cấp dưới dạng đối số hoặc stdin nếu không có đối số được cung cấp), với bản ghi hiện tại được lưu trữ $_. Điều đó tương tự như awkcủa $0.
Stéphane Chazelas

0

Có một chương trình được gọi là convmvcó thể giúp bạn.

Đơn giản chỉ cần sử dụng convmv --unescape /some_path/target_file. Nó sẽ làm một chạy khô.

Một khi bạn đã xác nhận, sử dụng convmv --notest --unescape /some_path/target_fileđể tiếp tục.

Trang chủ của chương trình này là: http://j3e.de/linux/convmv/

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.