sed replacing ASCII characters in Linux

时间:2015-11-12 11:18:09

标签: regex linux bash sed hindi

I want to replace the ASCII/English characters in a file and keep the unicode characters in Linux environment

INSERT INTO text (old_id,old_text,old_flags) VALUES (2815829,'[[चित्र:Youth-soccer-indiana.jpg|thumb|300px|right|बचपन का खेल.एसोसिएशन फुटबॉल, ऊपर दिखाया गया है, एक टीम खेल है जो सामाजिक कार्यों को भी प्रदान करता है।]]\n\n\'\'\'खेल\'\'\', कई [[नियमों]] एवं [[रिवाजों]] द्वारा संचालित होने वाली एक [[प्रतियोगी]] गतिविधि है। \'\'खेल\'\' 

I have tried

~$ sed 's/[^\u0900-\u097F]/ /g' hi.text but the range

but i get

sed: -e expression #1, char 23: Invalid range end

I also tried this and it seems to work but not fully

sed 's/[a-zA-Z 0-9`~!@#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' enwiki-latest-pages-articles-multistream_3.sql  >result.txt

Can anyone tell me how to get the sed working with the unicode range regex

3 个答案:

答案 0 :(得分:4)

ASCII codes are in the range 0 to 127 inclusive. From that range, 0-31 and 127 are control characters. Unicode encoded as UTF-8 uses data bytes from the range 128 to 255 inclusive.

Because sed is line-oriented, newline (code 9 is control/J) is treated specially. Your file may include tab (code 8) and carriage return (code 13). But in practice you likely only care about tabs and printable ASCII.

Tilde (~) is code 126 (something handy to know).

So:

sed -e 's/[ -~\t]/ /g'

where \t is ASCII tab (and depending on implementation you may need a literal tab) will remove all of the printable ASCII, leaving untouched newline and UTF-8.

答案 1 :(得分:2)

PERL

If you don't mind using perl try a mnemonic:

# this version replace each group also newlines
perl -pe 's/[[:ascii:]]/ /g;' filename

UPDATE: Using @user1516947 example i've slightly modified the perl solution to collapse multiple ascii chars into one space (and remove unwanted leading and trailing spaces):

perl -pe 's/[[:ascii:]]+/ /g; s/^\s+|\s+$//g' filename

Command line usage example based on sample input:

echo "INSERT INTO text (old_id,old_text,old_flags) VALUES (2815829,'[[चित्र:Youth-soccer-indiana.jpg|thumb|300px|right|बचपन का खेल.एसोसिएशन फुटबॉल, ऊपर दिखाया गया है, एक टीम खेल है जो सामाजिक कार्यों को भी प्रदान करता है।]]\n\n\'\'\'खेल\'\'\', कत्पत्ति ==\n\"खेल\" (\"स्पोर्ट\") शब्द की [[पुराने फ्रेंच]] शब्द \'\'देस्पोर्ट (desport)\'\' से उत्पत्ति हुई है, जिसका अर्थ \"अवकाश\" है।\n\n== इतिहास ==\n\n[[चित्र:Greek statue discus thrower 2 century aC.jpg|thumb|150px|right|2" | perl -pe 's/[[:ascii:]]+/ /g; s/^\s+|\s+$//g'

Output:

 चित्र बचपन का खेल एसोसिएशन फुटबॉल ऊपर दिखाया गया है एक टीम खेल है जो सामाजिक कार्यों को भी प्रदान करता है। खेल कत्पत्ति खेल स्पोर्ट शब्द की पुराने फ्रेंच शब्द देस्पोर्ट से उत्पत्ति हुई है जिसका अर्थ अवकाश है। इतिहास चित्र

(GNU) SED

Or in sed (in linux environment you have to modify LANG env to make the sed range valid):

# this version does not replace newlines
LANG=C sed 's/[\d0-\d127]/ /g' filename

A less readable sed version that replace all newlines (but one) too:

LANG=C sed ':a;N;$!ba;s/[\d0-\d127]/ /g' filename

答案 2 :(得分:1)

要摆脱ascii字符,你可以在范围内运行它,sed虽然如此,但是如果你想要那些已经消失,你需要在tr之后点击它。

echo -e "hi ☠ \nthere ☠" | LANG=C sed "s/[\x01-\x7F]//g" | tr -d '\n'
☠☠

相反,如果你想摆脱unicode字符,你可以指定unicode范围: echo -e "hi ☠ \nthere ☠" | LANG=C sed "s/[\x80-\xFF]//g"
你好 有