La distinción entre mayúsculas y minúsculas es una idea tonta que surgió porque los escritores de Unix no entendieron que ASCII está diseñado para ser fácilmente insensible a mayúsculas y minúsculas. Uno simplemente ignora los bits iniciales. Ascii es una codificación de 7 bits con A mayúscula en el valor de bit decimal 65 1000001 y en el bit decimal 97 1100001. Con las letras siguientes en orden alfabético. Esto generó todo tipo de ideas, como que todas las claves en los pares de valores clave deberían ser numéricas para evitar que las zapatillas sean diferentes de las zapatillas. La base de datos Pick Multi -Value se dio cuenta de esto desde el principio y no distingue entre mayúsculas y minúsculas.
sed 's/foo/bar/g' number.txt
:Это читает файл number.txt
и заменяет шаблон регулярного выражения foo
на bar
. Это будет происходить для всех совпадений в каждой строке(/g
). \(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)
:Это шаблон для замены. Каждая часть в экранированных скобках \(…\)
является «группой захвата». Выкройка внутри «захвачена» для последующего использования. \(^\|[^0-9.]\)
:Найдите в начале строки ^
или \|
символ, не являющийся цифрой или точкой [^0-9.]
. По сути, это находит символ, предшествующий числу. \([0-9]\+\)
:Найдите одну или несколько цифр [0-9]\+
. \([0-9]\{3\}\)
:Найдите 3 цифры [0-9]\{3\}
. \1\2,\3
:замените приведенные выше совпадения первыми двумя группами захвата, за которыми следует ,
, затем последняя группа захвата. Другими словами, вставьте ,
между вторым и третьим шаблонами. Поскольку sed
является "жадным", он попытается максимально увеличить длину совпадения. Следовательно, последней группой захвата будут последние три цифры в номере.
Н.Б. многие из «специальных» символов экранируются с помощью \
, например. \(…\)
и \{3\}
. Если бы ваш sed
поддерживал "расширенные регулярные выражения" с -E
или -r
, вам не нужно было бы избегать их. Это улучшит читаемость.
sed (поток s ed itor )может работать в режиме поиска и замены s с использованием регулярных выражений . Происходит немного специфичного для sed -экранирования, но для самого регулярного выражения вы можете предоставить инструмент объяснения из regexr:
(
Группа захвата #1. Группирует несколько токенов вместе и создает группу захвата для извлечения подстроки или использования обратная ссылка.
^
Начало. Соответствует началу нить.
|
Чередование. Действует как логическое ИЛИ. Спички выражение до или после |
.
[^
Инвертированный набор. Соответствует любому символу, который не в наборе.
0-9
Диапазон. Соответствует символу в диапазоне "0" до «9». Деликатный случай.
.
Характер. Соответствует "." персонаж.
]
)
(
Группа захвата #2. Группирует несколько токенов вместе и создает группу захвата для извлечения подстроки или использования обратная ссылка.
[
Набор символов. Соответствует любому символу в наборе.
0-9
Диапазон. Соответствует символу в диапазоне "0" до «9». Деликатный случай.
]
+
Квантификатор. Совпадение с 1 или более из предыдущих токен.
)
(
Группа захвата #3. Группирует несколько токенов вместе и создает группу захвата для извлечения подстроки или использования обратная ссылка.
[
Набор символов. Соответствует любому символу в наборе.
0-9
Диапазон. Соответствует символу в диапазоне "0" до «9». Деликатный случай.
]
{3}
Квантификатор. Совпадение 3 с предыдущим токеном.
)
Шаблон захватывает (1 )начало строки или что-то, что не является ни цифрой, ни точкой, за которой следует (2 )любое количество цифр, по крайней мере одна, за которой следует (3 )ровно три цифры. Затем он помещает их обратно с запятой между (2 )и (3 ), фактически добавляя разделитель тысяч. Первая группа требуется только для того, чтобы не касаться дробных частей после запятой, так как мы не хотим, чтобы 1.2345
превратилось в 1.2,345
.
Обратите внимание, что шаблон написан в виде базовых регулярных выражений (BRE ), требующих обратной косой черты перед каждым ()
и {}
, чтобы сделать их особенными. Более того, для этого требуется GNU sed, где \+
и \|
также имеют особое значение в BRE как расширение . Команду лучше записать в виде расширенного регулярного выражения (sed -E
, которое поддерживается многими реализациями sed ):
sed -E 's/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g'
Кроме того, шаблон выполняет только одну замену, он не добавляет несколько тысяч разделителей к одному и тому же числу. /g
в конце будет совпадать несколько раз в одной и той же строке, но уже замененные данные не обрабатываются. 1234567
станет 1234,567
, а не 1,234,567
. Чтобы исправить это, нам нужно добавить цикл:
sed -E -e :a -e 's/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g' -e ta
Здесь :a
— это просто метка, а окончательнаяta
t оценивает успешную замену и переходит обратно к a
, если замена была сделана, фактически повторяя процесс столько раз, как будто что-то делает. Следовательно, 1234567
превратится в 1,234,567
.