Bash: обрезать параметр с обоих концов - PullRequest
3 голосов
/ 16 июня 2010

Привет!

Это хорошо известные шаблоны расширения параметров Bash:

$ {параметр # слово} , $ {параметр ## слово}

и

$ {параметр% word} , $ {параметр %% word}

Мне нужно отрубить одну часть от начала и другую часть от конечного параметра. Не могли бы вы посоветовать что-нибудь для меня, пожалуйста?

Ответы [ 4 ]

1 голос
/ 16 июня 2010

Если вы используете версию Bash> = 3.2, вы можете использовать сопоставление регулярного выражения с группой захвата, чтобы получить значение в одной команде:

$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ [[ $path =~ ^.*/([^/]*)/.*$ ]]
$ echo ${BASH_REMATCH[1]}
ABC

Это будет эквивалентно:

$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ path=$(echo "$path" | sed 's|^.*/\([^/]*\)/.*$|\1|p')
$ echo $path
ABC
0 голосов
/ 17 июня 2010

Я бы настоятельно рекомендовал использовать массивы bash, поскольку их производительность чуть более чем в 3 раза выше, чем при сопоставлении с регулярными выражениями.

$ path='/xxx/yyy/zzz/ABC/abc.txt'
$ IFS='/' arr=( $path )
$ echo ${arr[${#arr[@]}-2]}
ABC

Это работает, сообщая bash, что каждый элемент массива отделяется косой чертой / через IFS='/'. Мы обращаемся к предпоследнему элементу массива, сначала определяя, сколько элементов в массиве, с помощью ${#arr[@]}, затем вычитая 2 и используя его в качестве индекса массива.

0 голосов
/ 16 июня 2010

Это решение использует то, о чем просил Андрей, и не использует никаких внешних инструментов. Стратегия: используйте расширение параметра%, чтобы удалить имя файла, затем используйте ##, чтобы удалить все, кроме последнего каталога:

$ path=/path/to/my/last_dir/filename.txt

$ dir=${path%/*}     

$ echo $dir
/path/to/my/last_dir

$ dir=${dir##*/}

$ echo $dir
last_dir
0 голосов
/ 16 июня 2010

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

> xx=hello_there
> yy=${xx#he}
> zz=${yy%re}
> echo ${zz}
llo_the

Если вы не беспокоитесь об эффективности и просто хотите получить одну строку:

> zz=$(echo ${xx%re} | sed 's/^he//')
> echo ${zz}
llo_the

Имейте в виду, что этот второй метод запускает подоболочки- это не то, чем я бы занимался, если бы ваш сценарий работал быстро.

...