「検索」を使用してそのファイルのディレクトリに移動する方法


11

ファイルを見つけて、それが含まれているディレクトリを入力します。試しましたfind /media/storage -name "Fedora" | xargs cdが、もちろんis not a directoryエラーです。

親ディレクトリを1行のコマンドで入力するにはどうすればよいですか?


1
そして、複数の場所から複数のファイルがある場合はどうなりますか?
Sergiy Kolodyazhnyy 2017年

@Serg ImがFedora * .isoファイルを検索していますが、1つしかありません。1つ以上ある場合は、最初のディレクトリに入ると思います
Hrvoje T

bash with shopt -s globstarを使用すると、を実行できますがcd /media/storage/**/Fedora、最初の一致でglobの評価が停止することはありません(したがって、steeldriverのソリューションよりも遅くなります。インタラクティブな使用の場合、私が通常行うことは、マウスを使ってディレクトリ名をコピーして貼り付け、 (とALT +バックスペース私はしたくなかった後続のパスコンポーネントを取り除くために、必要に応じて)いますが、これに多くを行う場合、私はシェル関数は価値が作ることができ推測する。
ピーター・コルド

1
ところで、xargs cdおそらく動作しません。 cdシェル自体のコンテキストを変更する必要があるため、組み込みシェルとしてのみ機能します。方法はありませんxargs子プロセスはそれを行うことができますが。それが「もちろん」の意味である場合、またはfind印刷するパスにスペースが含まれている場合はIDKを使用します-d \n。スペースは、何も使用していないためxargsによって分割されます。またはfind -exec {} \;
Peter Cordes 2017年

注:このcdように実行することはできません。cd組み込みのbashであり、cd別のコマンドの場合は、dirを変更し(独自の)、終了します(シェルに戻ります。以前と同じ状態で、dirは変更されません)。
ctrl-alt-delor 2017年

回答:


14

少なくともGNU findを使用-printf '%h'している場合は、を使用してディレクトリを取得できます

       %h     Leading directories of file's name (all but the last ele‐
              ment).  If the file name contains no slashes (since it is
              in  the  current  directory)  the %h specifier expands to
              ".".

だからあなたはおそらくできるでしょう

cd "$(find /media/storage -name "Fedora" -printf '%h' -quit)"

-quit複数の引数を防ぐ必要があるcd場合には、複数のファイルが一致しました。


1
-quitもサポートされているとは限りません。NetBSDではと呼ばれ-exitます。unix.stackexchange.com
a / 62883/117599を

2
printfがない場合は、代わりに-exec dirnameを実行できますか?
ガイ

@Guy良いアイデアはい、それもうまくいくように聞こえます
steeldriver

6

steeldriverのソリューションに似てい-execdirますが、(findGNUやFreeBSDのようにサポートしている場合find)を組み合わせて使用​​しpwdます:

cd "$(find /media/storage -name "Fedora" -execdir pwd \; -quit)"

-quit結果が1つしかなく、ディレクトリ全体をクロールしても問題がない場合は、オプションです。NetBSDでは-exitあり、OpenBSDではありません。


そして何の\;ためですか?
Hrvoje T 2017

1
@HrvojeTだけのためのような-exec、それは伝えfind、実行するコマンドのパラメータの終わりについて。ただし、pwdここではパラメータなしで呼び出したいので、\;直後に置きます。
2017年

findexecdirをサポートしているが、サポートしていない実装はあります-printf %hか?私にはなさそうだ。残念ながら、POSIXではどちらも必要ありません:/
Peter Cordes 2017年

1
@PeterCordes FreeBSD's findfreebsd.org/cgi/man.cgi?find%281%29(FreeBSD 11インストールで確認済み)
phk

@PeterCordes NetBSD(netbsd.gw.com/cgi-bin/man-cgi?find++NetBSD-current)とOpenBSD(man.openbsd.org/OpenBSD-current/man1/find.1)でも同じです。Latterは-quit/ -exitをまったくサポートしていません。
2017年

5

見つけたディレクトリでfindに新しいシェルを実行させることができます。

exec find /media/storage -name "Fedora" -execdir "$SHELL" \;

その後、現在のディレクトリはFedoraという名前のファイルを含むディレクトリになります。;)

明らかに、これは、コマンドを対話的に入力している場合に、あなたが望むものに似た何かを行うだけです。


4

zsh

cd /media/storage/**/Fedora([1]:h)

cd呼ばれるファイルが含まれている最初の(アルファベット順)ディレクトリにFedora

  • **:任意のレベルのディレクトリ(非表示のディレクトリはデフォルトで省略されています。D含めるにはglob修飾子を使用します)
  • [1]:最初のみ
  • :hヘッド修飾子:dirnameを取ります。

とは逆にcd "$(find ...)"、ディレクトリ名が改行文字で終わる場合にも機能します。もう1つの利点は、一致するディレクトリがない場合、一致ないエラーメッセージが表示されることです(ほとんどのシェルでcd ""は何も通知せずに何もしません)。

欠点は、/media/storage戻る前に全体をクロールすることです。


bashではcd、複数の引数を指定した場合でもとにかく最初の引数のみを参照するため、パスにスペースがない場合はcd $(dirname /media/storage/**/Fedora)(を使用してshopt -s globstar)機能します。適切に引用するには、bash配列が最も簡単だと思いますtarget=(/media/storage/**/Fedora); cd "${target%/*}"。しかし、その時点では、インタラクティブにそれを思い付くよりも、マウスを使用して検索出力をコピー/貼り付けする方が速いでしょう。
ピーターコーデス

2
@PeterCordes、多くのdirname実装は複数の引数を受け入れません。スペースではなく、現在の文字$IFS(デフォルトではスペース、タブ、改行)とワイルドカード文字に注意してください。かどうかという注意bashさんがcd複数の引数を受け付けますが、それが(コンパイルされた方法によって異なりCD_COMPLAINSconfig-top.h)。の将来のバージョンでbashも、最終的にzshのように2つのarg機能が実装されると想像できます。
ステファンChazelas

ありがとう。GNU coreutils dirnameマンページを見たところです。とにかくdirnameバージョンはひどいです。それが機能する場合に備えて、インタラクティブに試すことができるものとして、私はそれだけを述べました。私の配列ベースのバージョンは、これらの問題のいずれにも悩まされていません。なぜなら"${target%*/}"、最初の配列要素(/Fedoraストリップされた)だけに拡張されるからです。バージョンはパス名に含まれる可能性のある文字に対して完全に堅牢だと思います。
Peter Cordes
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.