Как преобразовать *текст* к {\\, я пишу сообщение} с sed?

Я изменил к лучшему @user-unknown's решение немного путем сохранения текущего dir, выполнения произвольного теста, затем восстановления исходного dir прежде, чем возвратиться с ответом. Это более гибко, потому что можно протестировать на что-либо.

Я также предусматриваю дополнительный второй аргумент, который говорит, как высоко пойти.

https://gist.github.com/1577473

#!/bin/bash

# Use this script instead of ~/.rvm/bin/rvm-prompt
# and the output of rvm-prompt will show up in your command prompt
# only if you are in a Ruby project directory.

# see http://stackoverflow.com/a/4264351/270511
# and http://unix.stackexchange.com/questions/13464/is-there-a-way-to-find-a-file-in-an-inverse-recursive-search

upsearch () {
  the_test=$1
  up_to=$2
  curdir=`pwd`
  result=1

  while [[ "`pwd`" != "$up_to" && "`pwd`" != '/' ]]; do
    if eval "[[ $the_test ]]"; then
      result=0
      break
    fi
    cd ..
  done
  cd $curdir
  return $result
}

if upsearch '-e Gemfile || ! -z "$(shopt -s nullglob; echo *.gemspec *.rb)"' ; then
  ~/.rvm/bin/rvm-prompt
fi

3
25.01.2013, 16:12
2 ответа

Предположение, что каждое возникновение *some text* находится на одной строке (т.е. не разделение через несколько строк):

sed -r 's/\*([^*]+)\*/{\\i \1}/g' file
3
27.01.2020, 21:17
  • 1
    выглядит хорошим, всего один \пропущенный (возможно, посредством автоформатирования):-r's sed /* ([^*] +)*/{\\\\i \1}/g' файл –  Inno 25.01.2013, 16:44
  • 2
    я сделал это этот путь на трех шагах: sed-e "s/^*/{\\\\i/g"-e "s/*/{\\\\i/g"-e "s / */}/g" файл –  Inno 25.01.2013, 16:45
  • 3
    Это может зависеть от который sed Вы используете. Я получаю тот же вывод с \\\i как с \\i. Я использую 'GNU sed версия 4.2.1' –  Peter.O 25.01.2013, 16:47
  • 4
    Обратите внимание, что синтаксисом является конкретный GNU, так должен был бы быть адаптирован при портировании к системе не-GNU. –  Stéphane Chazelas 25.01.2013, 16:48
  • 5
    Это работает на окнах.Большое спасибо. –  Inno 25.01.2013, 16:48

С любым POSIX sed, и если *...* может охватить несколько строк, Вы могли сделать:

sed -e :1 -e 's/\*\([^*]\{1,\}\)\*/{\\i \1}/g;/\*/!b' -e '$q;N;b1'

Обратите внимание что некоторые sed реализации имеют относительно низкий предел на размер их пространства шаблона, таким образом, они могут перестать работать если *...* охватите слишком много (длинных) строк.

С жемчугом:

perl -0777 -pe 's/\*(.*?)\*/{\\i $1}/gs'

Но остерегайтесь этого, это хлебает целый файл в памяти до выполнения замен, которые могли быть проблемой для огромных файлов. Также отметьте это perl имеет a -i опция обновить файл на месте (который некоторые sed реализации одолжили),

2
27.01.2020, 21:17

Теги

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