Как заставить Bash расширить подстановочные знаки в переменных? - PullRequest
26 голосов
/ 14 января 2011

Я пытаюсь добиться того же эффекта, что и при наборе

mv ./images/*.{pdf,eps,jpg,svg} ./images/junk/  

в командной строке, внутри скрипта bash. У меня есть:

MYDIR="./images"
OTHERDIR="./images/junk"  
SUFFIXES='{pdf,eps,jpg,svg}'
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/"

, который при запуске выдает неожиданную ошибку:

mv: rename ./images/*.{pdf,eps,jpg,svg} to ./images/junk/*.{pdf,eps,jpg,svg}: 
No such file or directory

Как правильно процитировать все это, чтобы mv действительно выполнил желаемое расширение? (Да, есть множество файлов, которые соответствуют шаблону в ./images/.)

Ответы [ 3 ]

27 голосов
/ 14 января 2011

Удаленный ответ был на правильном пути.Небольшое изменение вашей попытки:

shopt -s extglob
MYDIR="./images"
OTHERDIR="./images/junk"  
SUFFIXES='@(pdf|eps|jpg|svg)'
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/"

Раскрытие скобки выполняется до раскрытия переменной, но раскрытие переменной выполняется до раскрытия пути.Таким образом, фигурные скобки все еще являются фигурными скобками, когда переменная раскрывается в вашем оригинале, но когда переменная вместо этого содержит элементы пути, они уже были раскрыты, когда расширение пути завершено.

8 голосов
/ 14 января 2011

Вам нужно будет оценить эту строку, чтобы она заработала, например, так:

MYDIR="./images"
OTHERDIR="./images/junk"  
SUFFIXES='{pdf,eps,jpg,svg}'
eval "mv \"$MYDIR\"/*.$SUFFIXES \"$OTHERDIR/\""

Теперь у вас есть проблемы, в частности, если вы не доверяете $SUFFIXES, этоможет содержать инъекционную атаку, но для этого простого случая все должно быть в порядке.

Если вы открыты для других решений, вы можете поэкспериментировать с find и xargs.

0 голосов
/ 05 октября 2018

Вы можете написать функцию:

function expand { for arg in "$@"; do [[ -f $arg ]] && echo $arg; done }

, затем вызвать ее с тем, что вы хотите расширить:

expand "$MYDIR/"*.$SUFFIXES

ВыВы также можете сделать это сценарием expand.sh, если хотите.

...