Bash: передача фигурных скобок как аргументы для избиения функции

Можно добавить число перед 'вперед', и оно прокрутит строки N, не полное. Таким образом, если Ваше окно терминала является 40 строками, ввести 38f начинать прокручивать только 38 строк, оставляя последние 2 строки от последней 'страницы'. Из страницы справочника:

   SPACE or ^V or f or ^F
          Scroll forward N  lines,  default  one  window  (see  option  -z
          below).   If  N  is  more  than  the screen size, only the final
          screenful is displayed.  Warning: some systems use ^V as a  spe‐
          cial literalization character.

   z      Like  SPACE,  but  if  N is specified, it becomes the new window
          size.

   b or ^B or ESC-v
          Scroll backward N lines,  default  one  window  (see  option  -z
          below).   If  N  is  more  than  the screen size, only the final
          screenful is displayed.
4
03.03.2018, 17:18
2 ответа

Когда Вы работаете findinfiles {*.js,*.html,} {release,dev,} "span", вот то, что происходит:

  1. Синтаксические анализы Bash заключают в кавычки и разделяют команду на слова: findinfiles, {*.js,*.html,} {release,dev,} span.
  2. Bash разворачивает фигурные скобки, приводящие к списку слов findinfiles, *.js, *.html, release, dev, span.
  3. Bash разворачивает подстановочные шаблоны *.js и *.html к списку соответствия именам файлов. Если никакое имя файла не соответствует ни одному шаблону, он оставлен в покое.
  4. Bash ищет имя findinfiles, узнает, что это - функция и выполняет функцию с предоставленными параметрами.

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

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

findinfiles () {
  local patterns="$1" excludes="$2" pattern="$3"
  shift 3
  typeset -a cmd dirs
  if [[ $# -eq 0 ]]; then dirs=(.); else dirs=("$@"); fi
  cmd=(grep --color=auto -iRnHr)
  local IFS=,
  for x in $patterns; do
    cmd+=("--include=$x")
  done
  for x in $excludes; do
    cmd+=("--exclude-dir=$x")
  done
  "${cmd[@]}" "${dirs}"
}

Объяснения:

  • Сохраните первые три параметра в локальных переменных. Любые дополнительные параметры являются каталогами для поиска в.
  • Набор dirs к списку дополнительных параметров. Если нет ни одного, использовать . (текущий каталог) вместо этого.
  • Набор IFS к запятой. Когда сценарий содержит неупомянутое переменное расширение как $patterns и $excludes выше, оболочка выполняет следующее:

    1. Замените переменную ее значением.
    2. Разделите переменную на отдельные слова везде, где она содержит символ, который присутствует в IFS. По умолчанию, IFS содержит пробельные символы (пространство, вкладка и новая строка).
    3. Рассматривайте каждое слово как подстановочный шаблон и разверните его до списка соответствия файлам. Если нет никакого файла соответствия, оставьте шаблон в покое.

    (Для предотвращения этих шагов расширения используйте двойные кавычки вокруг подстановки переменных, как в patterns="$1" и так далее в сценарии выше.)

  • Функция создает командную строку для выполнения инкрементно в переменной типа массив cmd. В конце выполняется команда.

С другой стороны, Вы могли основываться на следующих настройках:

shopt -s extglob globstar
fif_excludes='release dev'
alias fif='grep --color=auto -inH $fif_excludes'

Команды выполнения как

fif span **/*.@(js|html)

Объяснения:

  • shopt -s extglob активируется @(js|html) форма подстановочного шаблона, который соответствует также js или html. (Эта опция активирует другие формы шаблона, см. руководство для деталей.)
  • shopt -s globstar actives шаблон **/ который соответствует подкаталогам на любой глубине (т.е. она выполняет рекурсивный обход).
  • Для изменения исключить списка (того, которое я ожидаю, часто не происходит) измените fif_excludes переменная.
5
27.01.2020, 20:50
  • 1
    за... статья! Это покрывает все ;-) –  oleq 01.12.2012, 13:04

удар расширяется {a,b,}1 кому: a1 b1 1..

Ваша команда расширяется до grep --color=auto -iRnHr --include=*.js --include=*.html --include= --exclude-dir=release --exclude-dir=dev --exclude-dir= span (в каталоге без любого js и файлов HTML, иначе это было бы включение для каждого файла),

Можно заключить параметры в кавычки, но это, вероятно, не идеально... findinfiles "{*.js,*.html,}" "{release,dev,}" "span" (globbing все еще необходим затем),

Необходимо затем смочь правильно развернуть его с eval, как эта версия:

function findinfiles() {
    eval "grep --color=auto -iRnHr --include=$1 --exclude-dir=$2 '$3'"
}
3
27.01.2020, 20:50

Теги

Похожие вопросы