Расширение переменной Bash

#bash #variable-expansion

#bash #переменная-расширение

Вопрос:

У меня есть строка, состоящая из каталогов с пробелом после каждого

 dirs="/home /home/a /home/b /home/a/b/c"
  

следующий код удаляет последний каталог в строке.

 dirs=${dirs% * }
  

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

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

Спасибо

Ответ №1:

 $ dirs="/home /home/a /home/b /home/a/b/c"
$ dirsa=($dirs)
$ echo "${dirsa[@]::$((${#dirsa[@]}-1))}"
/home /home/a /home/b
$ dirs="${dirsa[@]::$((${#dirsa[@]}-1))}"
$ echo "$dirs"
/home /home/a /home/b
$ dirs="/home"
$ dirsa=($dirs)
$ dirs="${dirsa[@]::$((${#dirsa[@]}-1))}"
$ echo "$dirs"
  

Или, знаете, просто все время сохраняйте ее в виде массива.

 $ dirs=(/home /home/a /home/b /home/a/b/c)
$ dirs=("${dirs[@]::$((${#dirs[@]}-1))}")
$ echo "${dirs[@]}"
/home /home/a /home/b
  

Комментарии:

1. круто, хотя немного сложно разобраться, что происходит. Скажите мне, прав ли я.

2. … не уверен, что случилось с остальной частью моего комментария. В любом случае, #dirs[@] преобразует мою строку в массив слов, а значение -1 сокращает ее на единицу?

3. ${#dirs[@]} задает длину массива. ${dirs[@]::} фрагментирует массив. Таким образом, он отсекает последний элемент из массива.

4. ах, спасибо. Я использую c ( , #), и синтаксис в Linux меня убивает.

Ответ №2:

Сначала удалите все пробелы, не являющиеся пробелами, с конца; затем удалите все конечные пробелы:

 dirs="/home /home/a /home/b /home/a/b/c"
dirs="${dirs%"${dirs##*[[:space:]]}"}" amp;amp; dirs="${dirs%"${dirs##*[![:space:]]}"}"
echo "$dirs"
  

Комментарии:

1. вау, у меня от этого болит мозг. У меня мало времени на банкомат, но я разберусь с этим позже и использую ignacio’s сейчас. хотя спасибо

Ответ №3:

Я уверен, что кто-нибудь предоставит что-нибудь получше, но

 case "$dirs" in (*" "*) dirs="${dirs% *}" ;; (*) dirs="" ;; esac
  

Ответ №4:

  $ dirs="/home /home/a /home/b /home/a/b/c"
 $ [[ $dirs =~ '(.*) (.[^ ]*)$' ]]
 $ echo ${BASH_REMATCH[1]}
 /home /home/a /home/b
 $ dirs="/home"
 [[ $dirs =~ '(.*) (.[^ ]*)$' ]]
 $ echo ${BASH_REMATCH[1]}