ディレクトリ内のファイルを探しているので、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
これは、コマンド置換がその値を返すときに削除されるためです。
答え2
これを使用して、検索しているファイルを含むディレクトリの名前を取得し、最後のエントリを取得するためにdirname
使用できます。tail -1
技術的にhead -2 | tail -1
2つ以上の場合は、それを使用して2番目のリストを取得できます。リストが1つしかない場合は1を返します。
良い:
cd $(dirname $(find . -name file.txt | tail -1))
または:
cd $(dirname $(find . -name file.txt | head -2 | tail -1))
これが本当に速いかどうかはわかりませんが、マウスでテキストを選択してコピーするのは面倒です。
これをシェルrcの関数で書くことができます(例えば).bashrc
。
function goto-file() {
file=$1
cd $(dirname $(find . -name $file | tail -1))
}
これにより、CLIの効率は次のように簡単になりますgoto-file file.txt
。
おそらく、より良いアプローチは、検索したいパスを通過することを許可することですか?これは私の関数に追加した関数です.bashrc
。
function goto-file() {
if [ $# -gt 2 -o $# -lt 1 ]; then
echo "Usage: goto-file [path] filename"
else
if [ $# -eq 2 ]; then
path=$1
file=$2
elif [ $# -eq 1 ]; then
path='.'
file=$1
fi
cd $(dirname $(find $path -name $file | tail -1))
fi
}
とても便利です。ありがとうございます。
答え3
xterm
ターミナルエミュレータを使用している場合はバインドできます。dabbrev-expand()
行動(emacs
'をまねる動的略語機能)をキーに接続します。
たとえば、リソースファイルを配置します(Xサーバー上のすべてのクライアントが影響を受けるようにXサーバーにロードするか、接続されているxrdb
Xサーバーに関係なく、すべてのxterm呼び出しがコンピューター上で行われるようにファイルxterm
に入れます)。XENVIRONMENT
) 影響を受ける) 例えば、
XTerm.VT100.translations: #override\
Meta <KeyPress> /: dabbrev-expand()
Alt+/次に、を使用して、xterm
画面に表示される内容に基づいて完成を提供します(カーソルに最も近いものから始めます)。
したがって、表示してfind ...
forを入力して展開し、末尾の部分を削除するだけです/folder/path/file-contents/file.txt
(または、useなどの単語区切り文字として処理するように構成されている場合は使用、追加、または使用)。cd /
Alt+/xterm
/
/folder/path/file-contents/file.txt
zsh
(:h)
Ctrl+W/
select-word-style
パスにスペース、制御文字、または分解された形式の文字が含まれている場合、この方法は機能しません。
シェル固有の文字(たとえば'
、、、、... )が含まれている場合は、その文字を引用する必要があります(ウィジェットを使用できます(デフォルトではこれを行うためにバインドされています"
))。;
&
zsh
quote-region
Alt+"
答え4
試してみることができますcdi
(https://github.com/antonioolf/cdi)
このコマンドラインツールは、ディレクトリ検索環境を改善するために作成されました(交換cd
)。
既定では、インタラクティブなコマンドラインディレクトリブラウザです。
あなたがしなければならないcdi
のは、コマンドを実行し、矢印キーを使用してフォルダをナビゲートしてから(Rightフォルダを入力して後ろにLeftリストをスクロールする)、目的のディレクトリを見つけたらクリックするだけで実際のコマンドを実行することです。UpDownEntercd
ストレージの表示