Извлекайте уникальные символы из разных файлов в UTF-8 - PullRequest
2 голосов
/ 18 января 2012

Я хочу извлечь уникальные символы из файлов ( UTF-8 , содержит азиатские символы)

Я почти достиг своей цели, но мне все еще не хватает некоторых очков.

Шаг 1 : положить все в один файл.

find ./ -name "*.ext" -exec cat {} > out.txt \;

Шаг 2 : Удалить разрывы строк:

cat out.txt |tr "\n" " ">i.txt

Шаг 3 :?

Думаю, мне следует отсортировать его по уникальным символам, но функция сортировки предназначена только для строк, а не символов.

Любая помощь? Спасибо

Было бы здорово, если бы я мог написать эту команду в одну строку!

Ответы [ 3 ]

2 голосов
/ 18 января 2012

Если «символы» означают Кластеры графемы или «воспринимаемые пользователем символы», тогда команда:

perl -C -ne'print grep {!$a{$_}++} /\X/g' *.ext

или

find -name \*.ext -exec perl -C -ne'print grep {!$a{$_}++} /\X/g' {} + >uniq.out

Чтобы включить подкаталоги и перенаправить вывод в файл uniq.out.

Считывает текст utf-8 из файлов *.ext и печатает все уникальные символы, воспринимаемые пользователем.

Примечание: он отличается от perl -C -ne'print grep {!$a{$_}++} split //', который работает с отдельными кодовыми точками Unicode (аналогично решению awk).

Пример

echo é é á á é é á á |perl -C -ne'print grep {!$a{$_}++} /\X/g'
# -> é éáá

echo é é á á é é á á |perl -C -ne'print grep {!$a{$_}++} split //'
# -> é éaá

echo é é á á é é á á |awk '{for(i=1;i<=NF;i++)if(!a[$i]++)print $i}' ORS='' FS=''
# -> é éaá

Примечание: и 'é', и 'á' являются отдельными символами (они могут отображаться неправильно: и ).

Чтобы увидеть разницу, вот кодовые точки с их именами.

Input

'e\u0301' LATIN SMALL LETTER E
          COMBINING ACUTE ACCENT
' '       SPACE
'é'       LATIN SMALL LETTER E WITH ACUTE
' '       SPACE
'a\u0301' LATIN SMALL LETTER A
          COMBINING ACUTE ACCENT
' '       SPACE
'á'       LATIN SMALL LETTER A WITH ACUTE
' '       SPACE
'e\u0301' LATIN SMALL LETTER E
          COMBINING ACUTE ACCENT
' '       SPACE
'é'       LATIN SMALL LETTER E WITH ACUTE
' '       SPACE
'a\u0301' LATIN SMALL LETTER A
          COMBINING ACUTE ACCENT
' '       SPACE
'á'       LATIN SMALL LETTER A WITH ACUTE

/\X/g выход на основе

'e\u0301' LATIN SMALL LETTER E
          COMBINING ACUTE ACCENT
' '       SPACE
'é'       LATIN SMALL LETTER E WITH ACUTE
'a\u0301' LATIN SMALL LETTER A
          COMBINING ACUTE ACCENT
'á'       LATIN SMALL LETTER A WITH ACUTE

awk и split // выход на основе

'e\u0301' LATIN SMALL LETTER E
          COMBINING ACUTE ACCENT
' '       SPACE
'é'       LATIN SMALL LETTER E WITH ACUTE
'a'       LATIN SMALL LETTER A
'á'       LATIN SMALL LETTER A WITH ACUTE

Второй выход пропускает последний COMBINING ACUTE ACCENT, который является частью 'á ' символа. вместо этого он печатает только 'a' (LATIN SMALL LETTER A).

1 голос
/ 18 января 2012

Это простой 1-вкладыш в awk

awk '{for(i=1;i<=NF;i++)if(!a[$i]++)print $i}' ORS= FS= *.ext

Примечание : удалить часть ORS=, если вы хотите, чтобы каждый символ находился в отдельной строке

0 голосов
/ 18 января 2012

Поскольку вы не указали perl в качестве тега, не обращайте внимания на этот ответ, если вы не находите его подходящим. Я не мог проверить это много, так как вы не опубликовали образцы данных, но вы можете попробовать -

perl -e 'while(<>){chomp;$uniqchar{$_}++ for split(//, $_)}print keys %uniqchar,"\n";' *.ext
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...