Если «символы» означают Кластеры графемы или «воспринимаемые пользователем символы», тогда команда:
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
).