ディレクトリ内のファイルを探しているので、findコマンドを使用すると、ファイルがあるディレクトリパスが表示されます。
前任者。
$find . -name file.txt
/folder/path/file-contents/file.txt
これで、ディレクトリにパスをコピーしてから、cdコマンドを使用してディレクトリを貼り付けるよりも早くディレクトリに入る方法があるかどうか疑問に思います。
また、findコマンドを使用した後に2つのパスが一覧表示されたら、そのパスをコピーして貼り付けることなく、2番目のパスにcdする方法はありますか?
端末の作業速度を上げるのに役立つかどうか疑問に思います。
ベストアンサー1
(bash
追加の下向き変更)
シェルでは、パターンの末尾にglobbing修飾子を追加して、zsh
globbingパターンの最後の一致を取得できます。([-1])
この例では、名前が終わるファイルを探します.sh
。
$ print -rC1 ./**/*.sh
./local/sbin/scheduled-backup.sh
./local/sbin/update-cvs.sh
./local/sbin/update-system.sh
./local/sbin/zerofill.sh
$ print -rC1 ./**/*.sh(.D[-1])
./local/sbin/zerofill.sh
.
修飾子におよびを追加すると、D
通常のファイルのみを探して隠された名前(dotglob
に設定されているようにbash
)も一致します。
見つかったファイルを含むディレクトリに変更するために使用できます。
$ cd ./**/*.sh(.D[-1]:h)
(ここではcsh / viスタイル:h
修飾子を使用して頭ファイルの(ディレクトリ名))
(パターンではなく)ファイル名を取るシェル関数として:
goto_file () cd ./**/$1(.D[-1]:h)
これはファイル名が正しいか(改行などを含まない)に依存しません。
では、bash
設定globstar
とdotglob
シェルオプションを最初に使用するという前提で、次のshopt -s globstar dotglob
操作を2つのステップで実行できます。
$ set -- ./**/*.sh
$ cd "$( dirname -- "${@: -1}" )"
これは、位置引数を一致するパス名のリストに設定し、呼び出しの最後の引数を使用し、dirname
その結果を一緒に使用しますcd
。ただし、を使用している場合、bash
globの拡張子が通常のファイルであるという保証はありません。
代わりに名前付き配列を使用できます。
$ stuff=( ./**/*.sh )
$ cd "$( dirname -- "${stuff[-1]}" )"
シェル関数としてファイル名(パターンではない)を取得します。
goto_file () {
local pathnames
pathnames=( ./**/"$1" )
cd "$( dirname -- "${pathnames[-1]}" )"
}
これを行うには、少なくともglobstar
このオプションを呼び出しシェルに設定する必要があります。ただし、必要に応じて設定できます。
goto_file () {
local pathnames
if [[ $BASHOPTS != *globstar* ]]; then
shopt -s globstar
trap 'shopt -u globstar' RETURN # unset globstar on return
fi
pathnames=( ./**/"$1" )
cd "$( dirname -- "${pathnames[-1]}" )"
}
バリアントと同様に、これはzsh
ファイル名が一般(改行文字などを含まない)には依存しませんが、ディレクトリ名は改行文字で終わることはできません。dirname
これは、コマンド置換がその値を返すときに削除されるためです。