sed заменяет символы ASCII в Linux

Я хочу заменить символы ASCII/английский в файле и сохранить символы Юникода в среде Linux.

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

я пытался

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

но я получаю

sed: -e выражение №1, символ 23: неверный конец диапазона

Я также пробовал это, и это, кажется, работает, но не полностью

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

Может ли кто-нибудь сказать мне, как заставить sed работать с регулярным выражением диапазона Unicode


person gaurus    schedule 12.11.2015    source источник
comment
что вы подразумеваете под кажется, работает, но не полностью?   -  person umläute    schedule 12.11.2015
comment
пожалуйста, упростите задачу. Рассмотрите возможность публикации 20 символов, смешанных ascii и unicode, и требуемого вывода из этих символов. Вы хотите удалить ascii или, как говорит ваш заголовок, заменить. В одной строке кода показан символ пробела, а во второй нет замещающего символа. Удачи.   -  person shellter    schedule 12.11.2015
comment
да, я хочу удалить (заменить нулем) все символы ascii и сохранить только хинди-слова unicode. Второе регулярное выражение, которое я пробовал, сохраняет некоторые специальные символы (что не требуется)   -  person gaurus    schedule 12.11.2015
comment
у нас уже есть ваше словесное описание. Нам нужны образцы! Помогите нам визуализировать вашу проблему, включив примеры входных данных (хорошо спроектированные), требуемые выходные данные и ваш текущий код, а также проблемы с вашими текущими выходными данными и любые сообщения об ошибках. См. stackoverflow.com/questions/33023436/ для хорошего примера (не совсем ваша область интересов, но очень хорошо организованный вопрос). Удачи.   -  person shellter    schedule 12.11.2015
comment
Ввод: вставьте в Text (Old_id, Old_Text, Old_flags) Значения (2815829, '[[चित्र: молодежь-склаг-индиана. है जो सामाजिक कार्यों को भी प्रदान करता है।]]\n\n\'\'\'खेल\'\'\', कत्पत्ति ==\n\खेल\ (\स्पोर्ट\) शब्द की [[पुराने फ्रेंच] ] शब्द \ '\' देस्पोर्ट (desport) \ '\' से उतшить हुई है है जिसक जिसका अा \ 'अवक से उत उत उत उत उत हुई हुई है है है जिसक000 .jpg | Большой | 150px | справа | 2 Ожидаемый вывод चित्र बचपन का खेल.एसोसिएशन फुटबॉल, ऊपर दिखाया गया है एक टीम खेल है जो स साजिक क| गय भी एक टीम है जो स स स स स स स स स स स स स स स क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क क   -  person gaurus    schedule 13.11.2015
comment
@ user1516947: я обновил свой ответ реализацией Perl, которая делает то, что вам нужно. В ожидаемом выводе, я думаю, вы пропустили удаление некоторых символов, таких как . и ,, и слов хинди, извлеченных в конечной части запроса (खेल कत्पत्ति खेल स्पोर्ट शब्द की पुराने फ्रेंच शब्द देस्पोर्ट से उत्पत्ति हुई है जिसका अर्थ अवकाश है इतिहास चित्र)   -  person Giuseppe Ricupero    schedule 15.11.2015


Ответы (3)


Коды ASCII находятся в диапазоне от 0 до 127 включительно. Из этого диапазона 0-31 и 127 являются управляющими символами. Юникод, закодированный как UTF-8, использует байты данных в диапазоне от 128 до 255 включительно.

Поскольку sed ориентирован на строку, новая строка (код 9 — это control/J) обрабатывается особым образом. Ваш файл может содержать вкладку (код 8) и возврат каретки (код 13). Но на практике вы, вероятно, заботитесь только о вкладках и печатном ASCII.

Тильда (~) — это код 126 (что полезно знать).

So:

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

где \t - вкладка ASCII (и в зависимости от реализации вам может понадобиться литеральная вкладка) удалит все печатные ASCII, оставив нетронутой новую строку и UTF-8.

person Thomas Dickey    schedule 12.11.2015

PERL

Если вы не возражаете против использования Perl, попробуйте мнемонику:

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

ОБНОВЛЕНИЕ: Используя пример @user1516947, я немного изменил решение perl, чтобы свернуть несколько символов ascii в один пробел (и удалить нежелательные начальные и конечные пробелы):

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

Пример использования командной строки на основе примера ввода:

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'

Выход:

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

(GNU) SED

Или в sed (в среде Linux вам нужно изменить LANG env, чтобы сделать диапазон sed действительным):

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

Менее читаемая версия sed, которая также заменяет все символы новой строки (кроме одной):

LANG=C sed ':a;N;$!ba;s/[\d0-\d127]/ /g' filename
person Giuseppe Ricupero    schedule 12.11.2015
comment
Делать широкие заявления о sed небезопасно, потому что существует несколько несовместимых версий, даже только для Linux. Я бы придерживался Perl для переносимости. - person tripleee; 15.11.2015
comment
@tripleee: вы правы, я отредактировал ответ, чтобы указать реализацию sed (gnu). По вашему опыту, этого достаточно? - person Giuseppe Ricupero; 15.11.2015
comment
Да, определенно улучшение, хотя я голосую за ответ Томаса. - person tripleee; 15.11.2015
comment
@tripleee Томас демонстрирует глубокие знания ASCII-кода, но его решение не работает так, как в Linux (запрошенная среда), оно также не удаляет символы новой строки. - person Giuseppe Ricupero; 16.11.2015
comment
Справедливое замечание, хотя я совсем не убежден, что ОП хочет сжать новые строки. - person tripleee; 16.11.2015

Чтобы избавиться от символов ascii, вы можете запустить его в диапазоне, sed съедает новые строки, поэтому, если вы хотите, чтобы они тоже исчезли, вам нужно нажать их с помощью tr после этого.

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

И наоборот, если вы хотите избавиться от символов юникода, вы можете вместо этого указать диапазон юникода: echo -e "hi ☠ \nthere ☠" | LANG=C sed "s/[\x80-\xFF]//g"
привет
есть

person Community    schedule 12.11.2015