Я хочу заменить определенные символы двойной ширины, найденные в файле, их эквивалентами одинарной ширины, используя выражение sed
.Это не совсем работает, как ожидалось, но отражает то, что я хочу сделать (это в скрипте bash): я смешал буквенно-цифровые диапазоны с некоторыми другими, которые я могу придумать, не уверен, нужно ли это разделить надва различных -e
аргумента, основанные на интервалах if и т. д.
sed -e 's,[0-9a-zA-Z()【】-一],[0-9a-zA-Z\(\)\[\]\-\-],g' ${file} > ${file}.cleaned
Файлы представляют собой текстовые файлы tsv (значения, разделенные табуляцией).Согласно команде file
тип: UTF-8 Unicode text, with CRLF line terminators
или (в другом случае) UTF-8 Unicode text, with no line terminators
Пример ввода:
Part Number
123-956-AA
343-213-【E】
XTE-898一(5)
Пример вывода:
Part Number
123-956-AA
343-213-[E]
XTE-898-(5)
Моя система - Ubuntu16.04, работающая в контейнере Docker, построенном из нашего базового образа, который построен из phusion/passenger-ruby23:0.9.19
, который имеет базовый образ (в конечном счете, базовый) ubuntu:16.04
, оболочка GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu)
, версия sedравно sed (GNU sed) 4.2.2
и результат команды locale
:
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Обновление:
Выбранное решение / ответ был 1) для использования y
команда (как и предлагали другие ответы) и в моем случае 2) для установки LL_ALL, как показано ниже, чтобы избежать ошибки, которую я получал с командой y
.Похоже, что диапазон не работает для команды y
, поэтому все символы должны идентифицироваться индивидуально (как я ранее ошибочно думал)
LC_ALL=en_US.UTF-8 sed 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()【】-一/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()[]--' file.tsv
Обновление 2:
Согласно предложению других ответчиков (один из них загадочно исчез), языковой стандарт, устанавливаемый для системы, был дополнительно исследован как решение вместо установки переменной среды в командной строке.Поскольку это среда контейнеров изображений Docker, я нашел решение для размещения в нашем базовом образе, которое решает проблему на уровне базовой системы.
Я добавил в наш базовый Dockerfile:
# Set the locale
RUN locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
и теперь команда locale
производит;
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
и теперь команда sed
работает следующим образом:
sed 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()【】-一/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()[]--' file.tsv
Asпримечание: я хотел бы, чтобы stackoverflow предоставил способ дать оценку нескольким ответам, поскольку первоначальные 3 ответа (опять же один исчезли) помогли мне найти решение, но мне пришлось выбрать только один.Это часто случается.