Как я могу сократить (1) верблюжьих слов? - PullRequest
8 голосов
/ 05 марта 2009

Есть ли в Bash простой способ разбить слово на верблюде на составляющие его слова?

Например, я хочу разделить aCertainCamelCasedWord на «Определенное слово в верблюжьих словах» и иметь возможность выбирать те поля, которые меня интересуют. Это тривиально делается с помощью cut (1), когда разделитель слов является подчеркиванием, но как я могу это сделать, когда слово занято верблюдом?

Ответы [ 4 ]

27 голосов
/ 05 марта 2009

sed 's/\([A-Z]\)/ \1/g'

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

$ echo "aCertainCamelCasedWord" | sed 's/\([A-Z]\)/ \1/g'
a Certain Camel Cased Word
3 голосов
/ 07 апреля 2011

Это решение работает, если вам не нужно разбивать слова на заглавные. Например, используя верхний ответ, вы получите:

$ echo 'FAQPage' | sed 's/\([A-Z]\)/ \1/g' 
F A Q Page

Но вместо этого с моим решением вы получите:

$ echo 'FAQPage' | sed 's/\([A-Z][^A-Z]\)/ \1/g'
FAQ Page

Примечание: это не работает правильно, когда есть второй экземпляр нескольких прописных слов, например:

$ echo 'FAQPageOneReplacedByFAQPageTwo' | sed 's|\([A-Z][^A-Z]\)| \1|g'
FAQ Page One Replaced ByFAQ Page Two
1 голос
/ 01 ноября 2011

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

echo 'FAQPageOneReplacedByFAQPageTwo' | sed 's|\([A-Z][^A-Z]\)| \1|g'
FAQ Page One Replaced ByFAQ Page Two

Итак, для этого требуется дополнительное выражение

 echo 'FAQPageOneReplacedByFAQPageTwo' | sed -e 's|\([A-Z][^A-Z]\)| \1|g' -e 's|\([a-z]\)\([A-Z]\)|\1 \2|g'
 FAQ Page One Replaced By FAQ Page Two
0 голосов
/ 06 марта 2009

Чистый Bash:

name="aCertainCamelCasedWord"

declare -a word                                 # the word array

counter1=0                                      # count characters
counter2=0                                      # count words

while [ $counter1 -lt ${#name} ] ; do
  nextchar=${name:${counter1}:1}
  if [[ $nextchar =~ [[:upper:]] ]] ; then
    ((counter2++))
    word[${counter2}]=$nextchar
  else
    word[${counter2}]=${word[${counter2}]}$nextchar
  fi
  ((counter1++))
done

echo -e "'${word[@]}'"
...