Как использовать расширенный шаблон со скобками в команде, переданной `bash -c`?

Как использовать расширенный шаблон со скобками в команде, переданной `bash -c`?

Я пытаюсь использовать расширенный глоб с bash -c, но не нашел способа заставить его работать.

Что я пробовал

  1. bash -c 'for f in *.!(ext); do echo $f; done'

    Результат:

    bash: -c: line 0: syntax error near unexpected token `('
    

     

  2. bash -c 'for f in *.!\(ext\); do echo $f; done'

    Результат:

    *.!(ext)
    

     

  3. bash -c 'for f in *.!$0; do echo $f; done' '(ext)'

    Результат:

    *.!(ext)
    

     

  4. bash -c 'for f in "*.!(ext)"; do echo $f; done'

    Результат:

    *.!(ext)
    

решение1

Чтобы использовать расширенный шаблон подстановки в bash, вам придется включить extglobопцию оболочки тем или иным способом.

Самый простой способ сделать это для встроенного bash -cскрипта — установить параметр оболочки с -Oпараметром в командной строке:

bash -O extglob -c 'script code here'

Вы также можете просто позвонитьshopt -s extglob в сценарии, но вы должны убедиться, что это сделано в отдельной строке, так как это изменяет способ, которым оболочка анализирует код (это изменяет синтаксис оболочки):

bash -c 'shopt -s extglob
         script code here'

Что касается вашей фактической задачи вывода всех имен, которые не заканчиваются строкой .ext:

bash -O extglob -O dotglob -O nullglob -c 'printf "%s\n" !(*.ext)'

При дополнительной установке параметров dotglobи nullglobскрипт будет сопоставлять скрытые имена и выводить одну пустую строку, если совпадений нет (вместо печати неразвернутого шаблона).

Обратите внимание, что ваш шаблон *.!(ext)исключит имена файлов, которые заканчиваются на ext(а не только на .ext)иимена файлов, не содержащие точку.

Связанный контент