Удаление непечатных символов с помощью sed не работает
Я работаю в AIX Unix и пытаюсь удалить непечатаемые символы из файла, на котором выглядят данные in Arizona w/ fiancÃÂÃÂÃÂ
в файле при просмотре в Notepad++ с использованием кодировки UTF-8. Когда я пытаюсь просмотреть файл в Unix, она получает ^ ▒▒ ^ ▒▒ ^ ▒▒ ^ ▒▒ ^ ▒▒ ^ ▒▒
Я хочу заменить все эти специальные символы пробелом, и мой вывод должен выглядеть так in Arizona w/ fianc
Я старался sed 's/[^[:print:]]/ /g' file
но он не удаляет эти символы. Мой язык указан ниже при запуске locale -a
C
POSIX
en_US.8859-15
en_US.ISO8859-1
en_US
Я даже пытался sed -e 's/[^ -~]/ /g'
и это не удаляло персонажей.
Я вижу, что другие ответы используются в стеке UTF-8
локаль с GNU sed, и это сработало, но у меня нет этой локали.
Также я использую ksh
,
0 ответов
Самый простой - strings
Самый простой способ сделать это - использовать strings
команда:
$ cat /tmp/asdf
in Arizona w/ fiancÃÂÃÂÃÂ
$ strings /tmp/asdf
in Arizona w/ fianc
Проблемы с этим подходом:
- Он не использует sed
- Он добавляет конец строки всякий раз, когда находит какой-либо непечатаемый символ (в вашем примере это должно быть нормально, поскольку все они сгруппированы в конце, но в противном случае он не удастся)
Самый уродливый - sed
с l
плюс sed
Постобработка
Теперь, если вы должны использовать sed
, то вот альтернатива:
$ sed -n l /tmp/asdf | sed -E 's/\\[[:digit:]]{3}//g; s/\$$//'
in Arizona w/ fianc
Здесь вы используете l
"сбрасывать" непечатаемые символы, преобразовывая их в восьмеричные представления, такие как \303
, затем удаляя все, что выглядит как восьмеричное значение, созданное таким образом, а затем удаляя $
что l
добавлен в конце строки.
Это довольно уродливо и может плохо взаимодействовать с вашим файлом, если в нем есть что-то, что начинается с обратной косой черты, за которой следуют три цифры, поэтому я бы остался с strings
вариант.
Лучше - sed
диапазоны с высокими символами Unicode
Тот, что ниже, тоже взломан, но выглядит лучше остальных. Оно используетsed
диапазоны, начинающиеся с "¡". Я выбрал этот символ, потому что это второй символ * в кодировке iso-8859-1, который также является разделом Unicode сразу после ASCII. Итак, я предполагаю, что у вас нет проблем с фактическими управляющими кодами, а вместо символов, отличных от ASCII (все, что представлено более 127 Decimal).
Для второго элемента в диапазоне просто выберите какой-нибудь нелатинский символ (японский, китайский, иврит, арабский и т. Д.), Надеясь, что он будет достаточно высоким в Юникоде, чтобы включать любой из ваших "непечатаемых" символов.
К сожалению, sed
не имеет [[:ascii:]]
спектр. Он также не принимает открытых диапазонов, так что вам понадобится этот прием.
$ sed 's/[¡-ﺏ]/ /g' /tmp/asdf
in Arizona w/ fianc
(*) Примечание: я выбрал второй символ в диапазоне, потому что первый символ - это неразрывный пробел, поэтому было бы трудно понять, что это не просто нормальный пробел.