sed – удаление нуля – / 08 / to / 8 /

Какую команду sed мне нужно использовать, чтобы включить / 08 / в / 8 /?

Я хочу избавиться от всех избыточных 0 в моем командном выходе.

Я добрался до одного лишнего лишнего 0.

sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp 

Выходы: at 12:27 AM on 5/[1-9]

 sed -ie 's/\/0?\//\/?\//g' ~/tmp 

Выходы: at 12:27 AM on 5/08

Полный скрипт:

 #!/bin/bash echo $@ > ~/tmp sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp AA=`awk '{print $2}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'` BB=`awk '{print $3}' ~/tmp` CC=`awk '{print $1}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'` DD=`awk '{print $5}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//'` EE=`awk '{print $6}' ~/tmp` FF=`awk '{print $4}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//'` if [ $# = 3 ]; then echo "at $AA $BB on $CC" elif [ $# = 6 ] && [ $CC = $FF ]; then echo "from $AA $BB to $DD $EE on $FF" elif [ $# = 6 ]; then echo "from $AA $BB on $CC to $DD $EE on $FF" fi rm ~/tmp 

Пример ввода вывода (alias = dt):

С текущей командой sed

dt 05/08/2017 02:27:25 AM

в 2:27 утра 5 / [1-9]


Без первой команды sed

dt 05/08/2017 02:27:25 AM

в 2:27 утра 5/08


Решено – третья строка заменена на sed -rie 's/\/0(.?)/\/\1/g' ~/tmp

dt 05/08/2017 01:03:56 AM

Выходы: в 1:03 утра по 5/8

4 Solutions collect form web for “sed – удаление нуля – / 08 / to / 8 /”

ПРИМЕЧАНИЕ . Это отредактированный ответ, чтобы сделать решение максимально возможным. Просмотрите историю изменений, чтобы узнать, что изначально было сделано, и посмотрите комментарии к проблемам с предыдущим ответом.

Ключевым моментом здесь является использование группировки через () и -r для расширенных регулярных выражений. Группировка шаблонов с помощью () позволит вам ссылаться на них на основе их позиции через нотацию \NUMBER . В частности, вот что я придумал:

 sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' 

Это гласит:

  • совпадение нуля или более символов, равных нулю
  • группируйте один или несколько ненулевых символов, которые следуют
  • затем найдите слэш, за которым следуют ноль или более символов, которые равны нулю
  • и группировать вместе один или несколько ненулевых символов, которые следуют

На практике это работает так с переменным числом нулей:

 $ echo "at 12:27 AM on 11/08/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' at 12:27 AM on 11/8/2017 $ echo "at 12:27 AM on 00000011/000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' at 12:27 AM on 11/8/00002017 $ echo "at 12:27 AM on 011/08/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' at 12:27 AM on 11/8/00002017 $ echo "at 12:27 AM on 000000011/0000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' at 12:27 AM on 11/8/00002017 

Обратите внимание, что это делает достаточно хорошей работы по сохранению того, что приходит в год, если это требуется. Если мы хотим избавиться от этого, мы также можем добавить третью группу.

 $ echo "at 12:27 AM on 005/0025/0002017" | sed -r 's/0*([^0]+)\/0*([^0]+)\/0*([^0]+)/\1\/\2\/\3/g' at 12:27 AM on 5/25/2017 

Это также хорошо работает с другими символами (что не обязательно, но приятно иметь):

 $ echo "at 12:27 AM on 0November/00Fifth/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\1\/\2/g' at 12:27 AM on November/Fifth/2017 
 sed -e 's/\<00*\([1-9]\)/\1/g' input_data 

Работа: это регулярное выражение ищет целое число [0-9], в левой части которого находится строка из 0s, и эти нули ограничены словом-break \< .

 sed -ie 's/\/0?\//\/?\//g' ~/tmp 

Во-первых, вы можете использовать другие символы, кроме косой черты как разделители для s/// , которые позволят вам использовать слэши без экранов. Во-вторых, как отмечает @ Stéphane , с -ie e будет приниматься за расширение для файла резервной копии, поэтому вы получите файл резервной копии с именем tmpe . Я бы изменил расширение (или удалил его) и переписал следующим образом:

 sed -i.bak -e 's,/0?/,/?/,g' ~/tmp 

Теперь легче увидеть, какой фактический шаблон соответствует этому: строки // и /0/ , буквальная строка /0?/ , Которая заменяется на /?/ . (В ERE « ? Будет соответствовать нулю или одной копии предыдущей группы, поэтому нулевой или один 0 ).

Вопросительный знак не является особенным в замене, поэтому он появится буквально. Как указано в других ответах, вам нужно использовать группировку ( (...) с ERE или \(...\) с BRE) для захвата частей шаблона, а затем \1 в замене, чтобы вернуть их.

Так что-то вроде этого:

 sed -i.bak -Ee 's,/0*([1-9]),/\1,g' ~/tmp 

Хотя обратите внимание, что по-прежнему потребуется косая черта спереди, поэтому первый ноль в 05/08/2017 не будет заменен.

Использование Racksh \< вероятно, является умным движением здесь, если вы хотите удалить ведущие нули из всех слов. Опять же, изменение 12:03:04 до 12:3:4 может быть не таким, каким вы хотите.


Последний пример изменения 05/08/2017 01:03:56 AM at 1:03 AM on 5/8 может быть сделано с помощью одной команды sed :

 $ echo '05/08/2017 01:03:56 AM' | sed -Ee 's,0*([0-9]+)/0*([0-9]+)/[0-9]+ 0*([0-9]+):([0-9]+):[0-9]+ ([AP]M),at \3:\4 \5 on \1/\2,' at 1:03 AM on 5/8 

Я не смотрел, какие другие форматы ввода вы хотели бы принять.

Вы не можете использовать регулярное выражение в заменяющем тексте. Ты имеешь в виду

 sed 's/0\([0-9]\)/\1/' 
  • sed заменить на backspace
  • команда sed добавить несколько строк
  • извлечение из строки в строку, а затем сохранение в отдельный файл
  • Печать строки между двумя круглыми скобками
  • format String с помощью sed
  • Однострочный шрифт для вставки новой строки текста (буквально регулярное выражение, а значит, и многих экранированных символов) в файле конфигурации перед определенной строкой?
  • совпадение шаблона N раз
  • Как удалить пустые строки в файле?
  • Извлечение частей строки, разделенной пробелами
  • Увеличьте число, используя ssh
  • Заменить сложную строку в нескольких файлах
  • Linux и Unix - лучшая ОС в мире.