1

Итак, в настоящее время на MacOS я настроил псевдонимы, как это ...

alias ...='cd ../..'
alias ....='cd ../../..'

Это позволяет мне перейти на несколько каталогов, набрав ... в моем терминале. Тем не менее, в моей предыдущей установке у меня было так, что ввод cd ... поднял бы несколько каталогов. Вначале я научился писать cd ... как мне изменить мои псевдонимы, чтобы он работал так, как я хочу?

2 ответа2

2

С помощью https://stackoverflow.com/questions/941338/how-to-pass-command-line-arguments-to-a-shell-alias ваша проблема может быть решена так:

alias cd='function _cd(){ cd ${1/.../..\/..}; }; _cd '

Расширение параметра в функции заменяет все вхождения '...' на '../.. ', таким образом, это не очень чистое решение, но я думаю, что оно все еще может быть приемлемым или может быть улучшено.

0

Вы не можете иметь псевдоним с пробелами. Чтобы сделать то, что вы хотите с псевдонимами, вам нужно воспользоваться этим свойством:

Если значение псевдонима, заменяющего слово, заканчивается на <blank>, оболочка должна проверить следующее командное слово на предмет замены псевдонима; этот процесс будет продолжаться до тех пор, пока не будет найдено слово, которое не является допустимым псевдонимом или значение псевдонима не заканчивается на <blank>.

(источник), поэтому cd и последовательные ... разрешены как псевдонимы.

Вам нужны такие псевдонимы:

cd='cd '
...='../..'
....='../../..'
# and so on

Но если у вас есть каталог с именем ls и вы cd ls , то ls также будет подвержен подстановке псевдонимов. Если ls является псевдонимом, это будет иметь неприятные последствия.

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

cd() {
       if [ "$#" -eq 0 ]; then
          command cd
       elif [ "$(printf '%s' "$1" | wc -l)" -eq 0 ]; then
          command cd "$(printf '%s' "$1" | sed '/^\.\.\+$/ {s|..|.|; s|.|../|g }')";
       else
          command cd "$1"
       fi
     }

(Примечание: чтобы заставить его работать в zsh , вызовите set -o POSIX_BUILTINS или замените каждую command на builtin в теле функции).

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

Есть дополнительная логика:

  • [ "$#" -eq 0 ] позволяет единственному cd (без аргументов) работать как надо.
  • [ "$(printf '%s' "$1" | wc -l)" -eq 0 ] запрещает sed изменять имена многострочных каталогов (например, foo<newline>..... которое является допустимым именем) , Обратите внимание, что для обычных имен (не содержащих символов новой строки) wc -l возвращает 0 (не 1 , POSIX не считает "строку" без завершения новой строки строкой), поэтому мы проверяем значение 0 .

И есть странность:

  • В s|..|.| первые две точки не являются буквальными точками, это регулярное выражение. Можно сказать, что это должно быть s|\.\.|.| но обратите внимание /^\.\.\+$/ гарантирует, что в строке есть только точки. То же самое относится и к первой точке в s|.|../|g

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .