sed - удаление нулей - / 08 / to / 8 /

В Управление питанием для USB, документация ядра , вы найдете сводку предварительных настроек отключения питания, относящихся к портовому устройству. :

echo 0 > power/pm_qos_no_power_off
echo 0 > peer/power/pm_qos_no_power_off # if it exists
echo auto > power/control # this is the default value
echo auto > /power/control
echo 1 > /power/persist # this is the default value

5
08.05.2017, 09:42
4 ответа

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

sed 's/0\([0-9]\)/\1/'
0
27.01.2020, 20:33
sed -ie 's/\/0?\//\/?\//g' ~/tmp

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

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

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

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


Последний пример изменения 08.05.2017 01:03:56 на в 1:03 08.05 можно выполнить с помощью одного 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

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

3
27.01.2020, 20:33

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

Ключевым моментом здесь является использование группировки с помощью ()и -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
6
27.01.2020, 20:33
sed -e 's/\<00*\([1-9]\)/\1/g' input_data

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

3
27.01.2020, 20:33

Теги

Похожие вопросы