Bashで `...`を `../..`でエイリアスを指定するには?

Bashで `...`を `../..`でエイリアスを指定するには?

Bashで...エイリアスを使用する方法は../..

私は他の答えがこれを許可することを知っていますが、alias '...'='cd ../..'別のコマンドを使用してディレクトリを最大2レベルまでアドレス指定できるようにしたいと思います。

cd ...
ls ...
realpath ...

私はこれを試しましたが、alias '...'='../..'それを使用しようとすると、次のような結果が得られます。

$ alias '...'='../..'
$ type ...
... is aliased to '../..'
$ cd ...
bash: cd: ...: No such file or directory

エイリアスはコマンド用であることを知っています。この場合、パスに対して同じ機能を達成する方法はありますか?

答え1

zshに切り替えるオプションがある場合は、そこでグローバルエイリアスを使用できます。

alias -g ...=../..

しかし、それにもかかわらず、...それ自体が完全な区切り文字として認識される場合にのみ拡張されます。echo ...または、またはではecho ...> file拡張されますが、または、または(echo ...)では拡張されません。)echo .../xecho ~/...echo "..."

bashでもzshでも、通常のcshスタイルのエイリアスは、コマンド位置にある間、またはスペース文字で終わる別のエイリアスが拡張された後にのみ拡張されます。ただし、zshではこのオプションを設定するとautocd入力や他のディレクトリになるため、../..コマンド名はcd ../..

$ set -o autocd
$ alias ...=../.. ....=../../..
$ ...

cdに入る道だろうが../..、また、alias ...='cd ../..'または...() cd ../..

より良い方法は何年も使ってきました。カーソルの左側の内容が終わるかどうかではなく、.挿入された内容にキーをバインドすることです。/.....

magic-dot() {
  if [[ $LBUFFER = (|*[[:blank:]/]).. ]]; then
    repeat ${NUMERIC-1} LBUFFER+=/..
  else
    zle self-insert
  fi
}
zle -N magic-dot
bindkey . magic-dot

入力は...すぐに視覚的にに変換され../..、もう一度押す.とに変わります../../..emacsモードにある場合は、+の後..に一般的な例方法を使用します(4回追加)。Alt4.../../../../../..数字プレフィックス処理。

以前は、埋め込まれた内容をコピー/貼り付ける際に邪魔になる場合がありましたが、...今は角かっこ貼り付け機能が導入され、これ以上問題になりません。テキストを入力するには、...3文字目の前に+を押すCtrlか、カーソルの左(上)が、、...で終わらないようにバックスラッシュ、引用符などを使用できます。v.$LBUFFER<blanks-or-slash>...\....\.whatever/'...'

上記の意図的な制限は、たとえばから拡張されないことsort -o...です...。代わりに使用してくださいsort -o ...cd '.../***'->同じだcd ...'/***'。より多くのコンテキストに拡張さ[[ $LBUFFER = (|*[^.]).. ]]れるように上記のテストを変更できます。ただし、これにより不要な位置に拡張される可能性が高くなります。...../..

たとえば、最大4つのレベル(拡張)を許可して、数値引数処理をより便利にすることができます。cd Alt+4.cd../../../..

magic-dot() {
  if (( NUMERIC )) && [[ $LBUFFER = (|*[[:blank:]/:]) ]]; then
    LBUFFER+=..
    (( NUMERIC-- ))
  fi
    
  if [[ $LBUFFER = (|*[[:blank:]/]).. ]]; then
    repeat ${NUMERIC-1} LBUFFER+=/..
  else
    zle self-insert
  fi
}
zle -N magic-dot
bindkey . magic-dot

@Gillesがコメントで述べたように、最新バージョンのbashには、キーにバインドされたコマンドでラインバッファを編集するための制限されたサポートが追加されているため、次のようなことができます。

insert_before_cursor() {
  # for the equivalent of zsh's repeat $1 LBUFFER+=$2
  local i
  for (( i = 0; i < $1; i++ )); do
    READLINE_LINE=${READLINE_LINE:0:READLINE_POINT}$2${READLINE_LINE:READLINE_POINT}
    (( READLINE_POINT += ${#2} ))
  done
}

magic-dot() {
  (( ${READLINE_ARGUMENT-1} > 0 )) || return
  if [[ -v READLINE_ARGUMENT && ${READLINE_LINE:0:READLINE_POINT} = ?(*[[:blank:]/]) ]]; then
    insert_before_cursor 1 ..
    (( READLINE_ARGUMENT-- ))
  fi

  if [[ ${READLINE_LINE:0:READLINE_POINT} = ?(*[[:blank:]/]).. ]]; then
    insert_before_cursor "${READLINE_ARGUMENT-1}" /..
  else
    insert_before_cursor "${READLINE_ARGUMENT-1}" .
  fi
}
bind -x '".":magic-dot'

# work around a bug in current versions of bash for the numeric
# argument to work properly, that means however that you lose the
# insert-last-argument normally bound to Meta-. (also on Meta-_)
bind -x '"\e.":magic-dot'

前述のとおり、まだ機能していませんが、bash 4.0以降$READLINE_LINE$READLINE_LINE_BUFFER一部の文書のスペルが間違っている場合とは異なり)と$READLINE_POINT5.2以降が必要です。$READLINE_ARGUMENT

答え2

これにはエイリアスを使用できません。エイリアスは、コマンドに引数として渡すのではなく、実行する項目に関するものです。変数を使用できますが、これは少し異なるものを入力することを意味します。ただし、短い変数名を使用している場合は、次の2文字しか使用できません。

$ pwd
/home/terdon/foo/bar
$ v="../.."
$ realpath "$v"
/home/terdon

これが有効な場合は、変数定義を~/.profileファイル~/.bash_profileに追加してからシェルセッションからアクセスできます。

v="../.."

答え3

目標を達成する方法はさまざまです

方法1:bashソースコードの修正

この方法はバージョンごとに異なりますが、これを行うには良い方法なので、まだお勧めします。私が修正したことは、builtins/cd.def絶対パスをチェックする前に、最初の引数が次のように設定されていることを確認することです。 (...エイリアスのように聞こえる)dirname../..

ステップ1:ダウンロードbash-5.1.16.tar

wget http://ftp.gnu.org/gnu/bash/bash-5.1.16.tar.gz

ステップ2:パッチの取得と適用bash_5.16_cd_two_dot.patch

tar -xf bash-5.1.16.tar.gz
cd bash-5.1.16
wget https://gist.githubusercontent.com/s0ubhik/6685effe6e46f6a840bb480c5d657933/raw/5736ce64cbb0b009d872c21f40d69c8ee2942b74/bash_5.16_cd_three_dot.patch
patch -p0 < bash_5.16_cd_three_dot.patch

ステップ3:コンパイルと実行

./configure
make
./bash

CD...強打

方法2:shoptでautocdを有効にする

このアプローチは必要に応じて正確には実行されませんが、賢いエイリアシング技術を使用する方が良いと思います。

shopt -s autocd

1つのディレクトリに戻るには、両方の..ディレクトリにおよびを使用します。../.. 自動ディスク

方法 3: 賢いエイリアスの使用

この方法は効果的ですが、使用されるさまざまなスクリプトに問題を引き起こす可能性があるため、お勧めできませんcd。ファイルに追加するか、.bashrc別のファイルを作成してそのファイルを.bashrc

cd_mod(){
  if [ "$1" == "..." ]; then
    \cd ../../
  else
    \cd $@
  fi
}

alias cd=cd_mod

cd_mod CD

答え4

...引数のようにエイリアスを直接使用することはできませんが、cd一部の人はエイリアスを使用してcd..すべてcd ..のコマンドに対して次のことを行うことができます。

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

一方、...

$ cat ~/mycd 
if [ "$1" = '...' ]
then
  # Use \cd to prevent recursion
  \cd ../..
else
  \cd "$1"
fi

それから

alias cd=". ~/mycd"

または、

mycd() { if [ "$1" = '...' ]; then \cd ../..; else \cd "$1"; fi; }
alias cd="mycd"

関連情報