Sed: Замените первые вхождения N символа

В ударе существует также autocd опция. Можно включить его при помощи shopt -s autocd:

pbm@tauri ~ $ shopt -s autocd
pbm@tauri ~ $ django # Now just type this
cd ./django    <- it's done automatically
pbm@tauri ~/django $
4
21.09.2011, 19:41
2 ответа

при чтении вопроса, я помнил, что, по крайней мере, GNU Sed (вероятно, не тот Вы имеете в Солярисе) имеет противоположную функцию, которую Вы хотите:

g: Примените замену ко всем соответствиям к regexp, не просто первое.

число: Только замените соответствие нумерующий regexp.

Note: the posix standard does not specify what should happen when

Вы смешиваете g и модификаторы числа, и в настоящее время существует не широко согласовано значение через sed реализации. Для GNU sed, взаимодействие определяется, чтобы быть: проигнорируйте соответствия перед нумерующего, и затем соответствуйте и замените все соответствия от нумерующий на.

Таким образом вместо:

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed 's/ /;/g5' 
one two three four five;six;seven

можно заставить более краткую команду достигать того, что Вы хотите путем выполнения:

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed -e 's/ /;/g' -e 's/;/ /6g'
one;two;three;four;five;six seven

Скажите нам, если Реализация Solaris имеет это feautre.

HTH

7
27.01.2020, 20:48
  • 1
    Да это действительно работает. Мне нравится изобретательность ответа. Однако это чувствует немного hackish, тот финал g6 может не быть ясно всем, не говоря уже о том, что поведение было бы непредсказуемо на других версиях sed. –  rahmu 21.09.2011, 19:43
  • 2
    Используя''; опасно при контакте с неизвестными данными, например. "seven;7". Значение \x00 был бы более безопасный выбор. Я не знаю если все seds дескриптор \x00, но они должны, по крайней мере, обработать \x01... они оба очень unliklely, чтобы быть в данных обычного текста. –  Peter.O 15.06.2012, 22:18

Будет легче придерживаться Вашей основной идеи, чем сделать некоторое повторяющееся манипулирование sed. Возможно, простое для цикла для создания шаблона поможет работать с.

pat=; for ((i=1; i<=5; i++)) ;do pat="$pat s/ /;/;"; done
sed -e "$pat" myfile

или просто обойдитесь без нескольких -e опции выражения, и просто группируют их всех с ; разделитель выражения.

sed -e "s/ /;/; s/ /;/; s/ /;/; s/ /;/; s/ /;/" myfile

Вот sed-единственная версия, которую Вы обычно, вероятно, не побеспокоите, но который действительно позволяет Вам указывать любое количество замен. (через {5}) ...

sed -nre ':check;G;/^.*\nx{5}$/{b print};s/^(.*)\n.*$/\1/;s/ /;/;t inc-tally;:print;P;x;s/.*//;x;b;:inc-tally;x;s/(.*)/\1x/;x;b check' myfile

Вышеупомянутая острота (?) немного страшна, таким образом, здесь она как структурирована код, чтобы быть названной через файл sed-сценария: sed -nrf "$fsed" myfile

:check             ## check the tally
 G                 ## pattern+=nl+hold
 /^.*\nx{5}$/{     ## we have the full complement of replacements
     b print       ## branch to print (and continue)
 }                 ##      
 s/^(.*)\n.*$/\1/  ##
 s/ /;/            ## change one space (if one is present) 
 t inc-tally       ## branch_on_substitute
:print             ## no more spaces to change
 P                 ## pattern_first_line_print
 x;s/.*//;x        ## kill the accumulated tally chars in hold   
 b                 ## branch to end of proc (continue)
:inc-tally         ##      
 x                 ## swap_pattern_and_hold
 s/(.*)/\1x/       ##
 x                 ## swap_pattern_and_hold
 b check           ## branch_unconditional 
3
27.01.2020, 20:48

Теги

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