У меня есть файл со списком единиц кода смайликов, и мне нужен еще один с «представлением графемы», чтобы передать их в grep. Если я повторю кодовый блок прямо в оболочке, он будет преобразован просто отлично:

echo $'\xF0\x9F\x98\x81'

Но если я запускаю массовое эхо, он печатает единицы кода, как если бы они были просто строкой

head emos_regex_utf8.lst | xargs -d '\n' -n1 echo
$'\xF0\x9F\x98\x81'
$'\xF0\x9F\x98\x82'
$'\xF0\x9F\x98\x83'
$'\xF0\x9F\x98\x84'
$'\xF0\x9F\x98\x85'

Моя цель - запустить grep для большого количества файлов, используя файл с графемами в качестве списка регулярных выражений. Строго говоря, я пытаюсь запустить, например:

cat ./20160711/* | jq '. | {text}' | grep -hEi -f graphemes.lst

/ 20160711/ содержит набор файлов json с кучей твитов, некоторые из которых получили смайлики в своих текстах, а некоторые из них получили смайлики в других областях (например, "цитируется"), которые я хочу игнорировать; поэтому мне нужно извлечь текстовое поле с помощью jq, что превращает мои кодовые точки javascript (из файлов .json) в их графическое представление. Вот почему мне нужны байт-коды.

Я написал тестовый файл testreg.lst, в котором есть одна графема и один байт-код; они разные смайлики, и я уверен, что у меня есть совпадение для каждого в моих файлах твитов:

testreg.lst:    
⛄
$'\xF0\x9F\x98\x81'

Запуск моего кода с этим файлом возвращает твит, содержащий первую запись, именно то, что я хочу.

$ cat ./20160711/* | jq '. | {text}' | grep -hEi -f testreg.lst
  "text": "RT @C5N: ⛄ #MiAmanecer: Nieve en Caviahue, provincia de Neuquén | Temperatura máxima: 3°"

Поэтому моя проблема заключается в том, чтобы превратить файл блоков кода в файл графем, чего я ожидал добиться с помощью cat emos_regex_utf8.lst | xargs -d '\n' -n1 echo > graphemes.lst , учитывая, что echo $'\xF0\x9F\x98\x81' напечатало только то, что мне нужно, но, похоже, я что-то не так делаю. Кстати, я бегу из Cygwin (uname: CYGWIN_NT-6.1)

Спасибо! :)

1 ответ1

0

Синтаксис $'...' не является какой-то волшебной нотацией "UTF-8 code unit", и это не echo которое его интерпретирует. Это ваша оболочка, которая выполняет - это синтаксис bash для выполнения общего C-подобного расширения с обратной косой чертой, и система фактически выполняет echo .

Будучи функцией оболочки, она специфична для командных строк (а именно для командных строк оболочки , а не непосредственно исполняемых, таких как xargs). Таким образом, очень маловероятно, что grep или другие инструменты будут автоматически понимать строки $'...' в текстовом файле.

Однако есть несколько способов перевести их вручную. Если у вас последняя версия Perl, попробуйте передать файл через:

| perl -pe 's/\$\x27(.*?)\x27/$1 =~ s@\\x([0-9A-F]{2})@chr hex $1@ger/ge'

или для более старых Perls:

| perl -pe 's/\$\x27(.*?)\x27/($tmp = $1) =~ s@\\x([0-9A-F]{2})@chr hex $1@ge; $tmp/ge'

Тем не менее, вы можете просто указать jq не заключать в кавычки вывод, во-первых, выбрав только значение, а не создавая бесполезный dict, затем используя опцию -r (raw output):

cat tweets.json | jq -r .text

(Если это массив твитов, используйте .[].text)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .