Làm cách nào để chỉ định các ký tự sử dụng mã thập lục phân trong `grep`?


27

Tôi đang sử dụng lệnh sau để phạm vi thiết lập ký tự grep cho mã thập lục phân 0900 (thay vì अ) đến 097F (thay vì). Làm cách nào tôi có thể sử dụng mã thập lục phân thay cho và व?

bzcat archive.bz2 | grep -v '<[अ-व]*\s' | tr '[:punct:][:blank:][:digit:]' '\n' | uniq | grep -o '^[अ-व]*$' | sort -f | uniq -c | sort -nr | head -50000 | awk '{print "<w f=\""$1"\">"$2"</w>"}' > hindi.xml

Tôi nhận được đầu ra sau đây:

    <w f="399651">और</w>
    <w f="264423">एक</w>
    <w f="213707">पर</w>
    <w f="74728">कर</w>
    <w f="44281">तक</w>
    <w f="35125">कई</w>
    <w f="26628">द</w>
    <w f="23981">इन</w>
    <w f="22861">जब</w> 
    ...

Tôi chỉ muốn sử dụng mã thập lục phân thay vì và trong lệnh trên.

Nếu hoàn toàn không thể sử dụng mã thập lục phân, tôi có thể sử dụng mã unicode thay vì mã thập lục phân cho bộ ký tự ('अ - व') không?

Tôi đang sử dụng Ubuntu 10.04


1
Bạn có nghĩa là "không làm việc" là gì? Cũng -vđảo ngược trận đấu, từ văn bản câu hỏi của bạn có vẻ như đó không phải là điều bạn muốn.
Christian.K

@ Christian.K Xin lỗi vì sự chậm trễ ... Tôi đã chỉnh sửa câu hỏi, xin hãy xem.

Tôi vẫn đang chờ đợi một câu trả lời thích hợp. :(
Dhrubo Bhattacharjee

Câu trả lời:


21

Nhìn vào câu hỏi này .

Văn bản thường được mã hóa bằng UTF-8; vì vậy bạn phải sử dụng các giá trị hex của các byte được sử dụng trong mã hóa utf-8.

grep "["$'\xe0\xa4\x85'"-"$'\xe0\xa4\xb5'"]"

grep '[अ-व]'

là tương đương và chúng thực hiện so khớp dựa trên miền địa phương (nghĩa là khớp phù hợp phụ thuộc vào quy tắc sắp xếp của tập lệnh devanagari (nghĩa là khớp không phải là "bất kỳ char nào giữa \ u0905 và \ 0935" mà thay vào đó là "mọi thứ sắp xếp giữa devanagari A và devanagari VA "; có thể có sự khác biệt.

Mặt khác, bạn có điều này (lưu ý -P):

grep -P "\xe0\xa4[\x85-\xb5]"

sẽ thực hiện khớp nhị phân với các giá trị byte đó .


2
Vui lòng giải thích tiền tố "["$'và hậu tố"]"
Jonathan Komar

6

Nếu thoát vỏ là đủ, bạn có thể sử dụng $'\xHH'cú pháp như thế này:

grep -v "<["$'\x09\x00'"-"$'\x09\x7F'"]*\s"

Như vậy đã đủ cho trường hợp sử dụng của bạn chưa?


echo 'अ-व' | hdcho tôie0 a4 85 - e0 a4 b5
enzotib

Thật vậy, OP đã đưa ra các giá trị unicode, chứ không phải các thập lục phân trong mã hóa UTF-8: - / Vì grepkhông được liên kết với bất kỳ lib nào, tôi đoán rằng không thể thực hiện chuyển đổi phạm vi bởi grep: - /
Stéphane Gimenez

1
Btw, zshcó thể diễn giải "\u0900""\u097F", nhưng hành vi sẽ dựa vào phạm vi được mã hóa UTF-8 là liên tục (có thể là như vậy).
Stéphane Gimenez

Không có grep -v "<[" $ '\ x09 \ x00' "-" $ '\ x09 \ x7F' "] * \ s" cung cấp đầu ra sau <wf = "16929"> x </ w> <wf = " 10995 "> F </ w> <wf =" 2548 "> FF </ w> <wf =" 762 "> FFFFFF </ w> <wf =" 655 "> FFFF </ w> <wf =" 266 " > xx </ w> <wf = "215"> FFF </ w> <wf = "117"> xxx </ w> .... Điều này không được mong đợi. :(, Tôi có thể sử dụng unicode thay vì mã thập lục phân hoặc bộ ký tự ('अ-व') không?
Dhrubo Bhattacharjee

6

Giá trị "thập lục phân" 0x0900mà bạn đã viết chính xác là giá trị của điểm mã UNICODE cũng nằm trong hệ thập lục phân.

mã thập lục phân 0900 (thay vì)

Tôi tin rằng những gì bạn muốn nói là điểm mã thập lục phân UNICODE : U0905.

Ký tự tại U-0900 không phải là ký tự bạn đã sử dụng : .
Ký tự đó là U0905 , một phần của trang Unicode này hoặc được liệt kê tại trang này .

Trong bash(được cài đặt theo mặc định trong Ubuntu) hoặc trực tiếp với chương trình tại: /usr/bin/printf(nhưng không phải với shprintf), một ký tự Unicode có thể được tạo bằng:

$ printf '\u0905'

$ /usr/bin/printf '\u0905'

Tuy nhiên, ký tự đó, xuất phát từ số điểm mã có thể được biểu thị bằng một số luồng byte tùy thuộc vào trang mã nào được sử dụng.
Rõ ràng \U09050x09 0x05trong UTF-16 (UCS-2, v.v.)
0x00 0x00 0x09 0x05trong UTF-32.
Nó có thể không rõ ràng nhưng trong utf-8, nó được thể hiện bởi 0xe0 0xa4 0x85:

$ /usr/bin/printf '\u0905' | od -vAn -tx1
e0 a4 85

Nếu miền địa phương của giao diện điều khiển của bạn là một cái gì đó tương tự en_US.UTF-8.

Và tôi đang nói về shell bởi vì nó là chuỗi biến đổi một chuỗi thành những gì ứng dụng nhận được. Điều này:

grep "$(printf '\u0905')" file

làm cho grep "thấy" nhân vật bạn cần.
Để hiểu dòng trên, bạn có thể sử dụng echo:

$ echo grep "$(printf '\u0905')" file
grep  file

Sau đó, chúng tôi có thể xây dựng một phạm vi ký tự, như bạn yêu cầu:

$ echo grep "$(printf '[\u0905-\u097f]')" file
grep [अ-ॿ] file

Đó là câu trả lời cho câu hỏi của bạn:

Làm cách nào tôi có thể sử dụng mã thập lục phân thay cho và व?


Đây là câu trả lời hay nhất --- nó giải quyết rõ ràng vấn đề về các đại diện của điểm unicode trong trình bao và chỉ ra cách quay lại giữa các mã hex.
stefano

2

chúng tôi muốn chuyển đổi trích dẫn kép không phải ascii và đóng trích dẫn kép thành trích dẫn kép thông thường ("). Ngoài ra, trích dẫn đơn không ascii thành trích dẫn đơn thông thường (').

để xem chúng trong tệp (vỏ bash Ubuntu):

$ grep -P "\x92" infile.txt  (single)
$ grep -P "\x93" infile.txt  (open double)
$ grep -P "\x94" infile.txt  (close double)

dịch chúng:

$ /bin/sed "s/\x92/'/g" a.txt > b.txt
$ /bin/sed 's/\x93/"/g' b.txt > c.txt
$ /bin/sed 's/\x94/"/g' c.txt > d.txt
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.