ディレクトリを変更するときにワイルドカード * が機能しないのはなぜですか?

ディレクトリを変更するときにワイルドカード * が機能しないのはなぜですか?

たとえば、私は自分のディレクトリにいます:

/home/myname

そして別のディレクトリに CD したいのです。

/home/pulsar/... 

他のディレクトリのかなり深いところまで移動する必要があるので、行全体を入力せずにこれを行うにはどうすればよいですか?試してみました

cd */thedirectoryiwanttogointo

しかし、それは機能しません。行全体を入力する必要があります。

答え1

ワイルドカードが機能しない理由としては、次のことが考えられます。

  • 指定した場所のワイルドカードに一致するものがなかった、または
  • 一致するものが複数ありました。

サブディレクトリ間を頻繁に移動するための通常のアプローチ (シェル内) は、CDPATH機能と およびpushdを使用することですpopd

このCDPATH機能 (おそらく tcsh で初めて登場) は、コロンで区切られたディレクトリのリストです。名前の親がthedirectoryiwanttogointo十分に一意である場合は、その親をリストに追加できます。

さらに詳しく読むには(まずシェルのマニュアル ページを参照してください):

pushdおよび はpopdよりも新しいですCDPATHが、それでも 1990 年代半ばのものです。これらを使用すると、それぞれのcdコマンドの実行中に現在のディレクトリを保存 (スタックに「プッシュ」) したり、復元 (スタックから「ポップ」) したりできます。詳細については、以下を参照してください。

他の人はシェル エイリアスまたはシンボリック リンクを使用します。これらは、よく知られている場所に行くときに最も便利です。

答え2

考えられるすべてのターゲット ディレクトリが の下にあり/home、ディレクトリ名に改行文字が含まれていないと仮定すると、次のシェル関数を使用できます。

cds() {
    cd "$(find /home -type d -name "$1" | head -n 1)"
}

$ cds thedirectoryiwanttogointo

もちろん、サブディレクトリとファイルの数/homeや、OS がすべてのツリーをメモリにキャッシュできるかどうかによって、パフォーマンスは大きく異なります。

GNU システムでは、代わりに次の構文を使用することで、ファイル名の改行文字に関して速度を上げ、信頼性を高めることができます。

cds() {
    cd "$(find /home -type d -name "$1" -print -quit)"
}

最初の一致が見つかるとすぐに検索が停止します。

引数はパターンとして扱われるので、次のように実行できることに注意してください。

cds 'foo*bar'

たとえば、名前が で始まりで終わるcd最初のディレクトリ (順序は指定されていません) に移動します。foobar

答え3

ワイルドカード拡張を使用して、システム上の任意の場所のパスを検索します。パターンを正しく指定すれば、それが可能です。

cd /**/thedirectoryiwanttogointo

デフォルトでzshとfishで動作します。Bashで最初にshopt -s globstar、 でtcshの場合set globstar、ksh93 の場合はset -o globstar、 、のyash場合はset -o extended-glob

これが機能するのは、ワイルドカードが/現在のディレクトリに対する相対パスではなく、 で始まる絶対パス内で使用され、**パターンの使用を選択すると任意の数のサブディレクトリに拡張されるためです。

これはうまくいくが、非常に長い時間がかかる可能性があるシェルはシステム全体を検索して一致するファイルを探す必要があります。検索スペースを小さくするために、プレフィックスを長くすると検索時間が短縮されます。

cd /home/pulsar/**/thedirectoryiwanttogointo/

ドリルダウンするほど、検索する回数が少なくなります。ディレクトリ ツリーがかなり少ない場合、この方法はそれほど時間がかからず、実際に使用できます。末尾に付けると、/展開がディレクトリのみに限定され、発生する可能性のあるあいまいさが 1 つ解消されます。

それでも一致するものが複数ある場合、結果はシェルによって異なります。bashとfishはあいまいさを無視してアルファベット順で最初に一致するものに切り替えます。tcshとyashはエラーを報告します。zshとkshはそれを高度なディレクトリ切り替え機能の1つを使用する試みとして解釈し、おそらくエラーを報告します。


同じディレクトリを繰り返し使用する可能性がある場合は、親ディレクトリをの中へCDPATH$FOOまたは、長いパスの代わりに使用できるシェル変数を作成する方がよいオプションです。**頻繁に使用する場合は、シェル変数を拡張と組み合わせて入力の手間を省くことができます。

答え4

常に同じ深いディレクトリにアクセスする場合、簡単な解決策の 1 つは、そのディレクトリへのシンボリック リンクを作成することです。

ln -s ~/foo/bar/baz/quux/etc/etc/etc/target ~/shortcut

以前にそのディレクトリに移動したことがある場合は、別の解決策として、コマンド履歴で目的の名前を検索します。Ctrl + R を押し、検索する文字を押します。これは bash に固有のものですが、最近のシェルのほとんどに同様の機能があると思います。

関連情報