У меня возникают проблемы со снижением синтаксиса sed для добавления различного числа ведущих нулей в числовую организационную схему. Строки, над которыми я работаю, выглядят как
1.1.1.1,Some Text Here
используя синтаксис Sed
sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"
Я могу получить ответ
01.01.01.01,Some Text Here
Однако то, что я ищу, это что-то, чтобы заполнить нулями до 2 цифр в полях 2 и 3 и 3 цифры в поле 4, чтобы все элементы имели стандартную длину в [0-9]. [0-9] { 2}. [0-9] {2}. [0-9] {3}
1.01.01.001,Some Text Here
За свою жизнь я не могу даже представить, как изменить границу, чтобы включить параметры, необходимые для привязки только к цифрам после точки. Я думаю, что это как-то связано с использованием \ b, которое, как я понимаю, соответствует нулевым символам на границе слова, но я не понимаю, почему мои попытки добавить точку в совпадение заканчиваются следующим образом:
sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang
sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:
1.01.01.1,Some Text Here
Кроме того, я ожидаю, что у меня возникнут дополнительные проблемы, если в заявлении содержится такой текст:
1.1.1.1,Some Number 1 Here
Это предрешенный вывод, что мне нужно по-настоящему изучить sed и все его сложности. Я работаю над этим, но ожидаю, что это конкретное заявление будет еще некоторое время доставлять мне неприятности. Любая помощь будет принята с благодарностью.
РЕДАКТИРОВАТЬ: Я нашел способ ... Это утверждение, кажется, делает то, что я ищу, но должен быть более элегантный способ сделать это.
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
Кроме того, синтаксически это вызовет проблемы, если в тексте появится похожий формат чисел ... похожий на:
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3
В этом случае это приведет к:
1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03
Решено Спасибо всем за помощь здесь. Я изначально решил проблему с ответом, который я принял ниже. Я чувствую, что решение было перенесено в Python как часть более крупного решения, использующего следующий вид:
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
s=sorted(reader, key=getPaddedKey)
источник
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
однако, я хотел бы знать, есть ли более элегантный подход.printf
(илиprintf
вызов в Awk) может быть более простым.Ответы:
Использование:
leading_zero.sh input.txt
Объяснение:
input.txt
output.txt
источник
perl
версия не удаляет обратную косую черту.Баш может справиться с этим. Это будет намного медленнее, чем Perl:
источник
printf
, разумный инструмент. (Awkprintf
также разработан и лучше разработан, чемbash
для обработки текста.) Также см. Почему использование цикла оболочки для обработки текста считается плохой практикой?Вы специально не спрашивали о
perl
решении, но вот так или иначе. Лично я думаю, что это немного легче читать, особенно когда разбито на несколько строк.Сначала вот одна строка:
Его результаты:
А вот
perl
сценарий разбит и прокомментирован (-n
флаг ставит неявныйwhile read; do ... done
цикл вокруг кода):источник
awk
будет работать тоже - тот же принцип, используяprintf
Вот один из возможных подходов:
sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
Примеры
Также работайте с этой строкой:
... и эта строка:
источник
Объяснение:
Используемый здесь метод заключается в том, чтобы посмотреть на окрестности чисел и принять меры на основе этого. Итак, 2-е и 3-е числа видят точку с обеих сторон, а 4-е число видит точку слева и запятую справа.
$ 1 устанавливается, когда регулярное выражение принимает путь 2-го или 3-го числа и, соответственно, точность заполнения равна 2. OTOH, для 4-го числа заполнение равно 3.
% cat file.txt
Полученные результаты:
источник