Bash: использование подстановочного знака в качестве аргумента сценария оболочки и возможность его расширения - PullRequest
0 голосов
/ 23 февраля 2020

Я столкнулся с конкретной проблемой c, которая на первый взгляд проста.

Если я наберу на своей оболочке bash подстановочный знак, соответствующий различным файлам:

$ myfile=probe_*.txt

и делать после:

$ echo $myfile

Я получаю список всех файлов, соответствующих шаблону, то есть:

$ probe_GCph.txt probe_GCsp.txt probe_GCsp_WL_GCph.txt probe_GCsp_XC.txt probe_GCsp_XC_WL_GCph.txt probe_WL.tx

Но теперь я хотел бы сделать шаблон probe_*.txt как аргумент $2 в функцию.

На данный момент, если я сделаю в bash функцию:

function multiple_files { myfile=$2
                          echo $1
                          echo $3
                          echo $myfile
                        }

Затем при следующем выполнении:

$ multiple_files . $myfile dir/

Тогда я получаю только первое имя файла probe_GCph.txt, которое печатается для третьего эха (echo $myfile) в определении функции bash.

Как можно Я передаю подстановочное имя файлов в качестве аргумента (здесь $ 2) и могу после этого развернуть его, чтобы перечислить все имена файлов, соответствующие функции bash?

Кажется, что существует конфликт между аргументом $ 2, который учитывает только первые расширенные файлы, равные probe_GCph.txt, и передачу подстановочного знака в качестве аргумента $ 2, не раскрывая его.

Как обойти эту проблему?

Ответы [ 3 ]

2 голосов
/ 23 февраля 2020

Напишите вашу функцию, чтобы принимать несколько аргументов вместо одного. Вот как работает большинство других инструментов (например, cp / mv / ls / grep / sed):

multiple_files() {
  first="$1"
  last="${@: -1}"
  files=( "${@:2:$#-2}" )

  echo "The first thing was $first"
  echo "The last  thing was $last"
  for file in "${files[@]}"
  do
    echo "One of the files is $file"
  done
}

multiple_files . probe_*.txt dir/

Это приводит к:

The first thing was .
The last  thing was dir/
One of the files is probe_GCph.txt
One of the files is probe_GCsp.txt
One of the files is probe_GCsp_WL_GCph.txt
One of the files is probe_GCsp_XC.txt

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

1 голос
/ 23 февраля 2020

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

$ ls
f1  f2  f3

$ function multiple_files { myfile=$2; echo $1; echo $2; echo $myfile;}
$ multiple_files '*' f\*
f1 f2 f3
f1 f2 f3
f1 f2 f3

Если вы не используете подстановочный знак, он раскрывается до вызова функции

$ multiple_files f*
f1
f2
f2

Чтобы напечатать подстановочный знак внутри функции, вам также необходимо включить переменную в кавычки. С eval тоже есть несколько хитростей:

$ function multiple_files { myfile=$2; echo $1; eval echo "$2"; echo "$2"; echo "$myfile"; eval echo "$myfile";}
$ multiple_files '*' f\*
f1 f2 f3
f1 f2 f3
f*
f*
f1 f2 f3
1 голос
/ 23 февраля 2020

Двойные кавычки позволяют избежать расширения глобуса оболочки, но позволяют замену переменных оболочки. Стоит отметить, что одинарные кавычки предотвращают глобальные (или подстановочные символы) расширения и интерполяции переменных.

TL; DR:

Вызывайте свою функцию следующим образом:

multiple_files . "$myfile" dir/
...