Правильно процитировать определение псевдонима bash - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть следующая команда, которую я пытаюсь ввести в псевдоним bash.Сама по себе команда работает нормально, но когда я пытаюсь создать псевдоним, я получаю следующие ошибки:

Команда

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr

Псевдоним

alias csfiles='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr'

Ошибка:

-sh: alias 0: not found
-sh: alias {} \; | sort nr: not found

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

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Ваш внешний find не делает ничего, что вы не могли бы сделать с простым шаром.Это исключает слой кавычек (вместе с процессом sh для каждого найденного каталога).

# Ignoring the issue of assuming no file name contains a newline
for d in ./*/; do
   echo "$(find "$d" -type f | wc -l) $d"
done

Просто определите функцию оболочки, чтобы исключить второй слой, наложенный на аргумент alias.

csfiles () {
  for d in ./*/; do
    echo "$(find "$d" -type f | wc -l) $d"
  done
}

Оставшиеся вызовы на find также могут быть заменены на цикл for, устраняя проблемное предположение об одной строке для имени файла:

csfiles () {
  for d in ./*/; do
    echo "$(for f in "$d"/*; do [ -f "$f" ] && echo; done | wc -l) $d"
  done
}

Вы можетеоставьте find, если он поддерживает первичный -printf, потому что вас не волнуют фактические имена файлов, просто вы получаете ровно одну строку вывода на файл.

csfiles () {
  for d in ./*/; do
    echo "$(find "$d" -type f -printf . | wc -l) $d"
  done
}
0 голосов
/ 20 ноября 2018

Вы можете использовать двойные кавычки вокруг определения, например:

alias foo="find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo \"\$(find \"{}\" -type f | wc -l)\" {}' \; | sort -nr"

Каждый литерал " внутри определения экранируется: \".

Примечание: Вам также необходимоизбежать внутренней подстановки команды, чтобы предотвратить ее расширение по времени определения псевдонима.Например, ... \$(...)


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

alias foo="find . -maxdepth 1 -mindepth 1 -type d -exec bash -c 'echo \"\$(find \"\${1}\" -type f | wc -l) \"\${1}\" \"' -- \"{}\" \; | sort -nr"
...