web-dev-qa-db-ja.com

ファイルを見つけて、Linuxでそのディレクトリにcdします

シェルスクリプトで、特定の名前のファイルを見つけて、そのディレクトリに移動してさらに操作を行うにはどうすればよいですか?

ここから、ファイルを別のディレクトリにコピーします(ただし、コンテキスト用にファイルを追加するだけで、すでにコピーできます)。

25
Candyfloss

次のようなものを使用できます。

_pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"
pax[/usr/bin]> _
_

これにより、最初のls通常ファイルが検索され、そのディレクトリに移動します。

各ビットの機能に関して:

  • 検索は_/_から始まり、下に検索して、ls(_-type f_)と呼ばれるすべての通常のファイル(_-name ls_)を一覧表示します。 findに追加して、取得するファイルをさらに制限できるものは他にもあります。
  • _head -1_を通る配管は、最初のものを除くすべてを除外します。
  • $()は、コマンドの出力を取得して、anotherコマンドのコマンドラインに配置する方法です。
  • dirnameは完全なファイル指定を取り、パスビットを提供できます。
  • cdはそのディレクトリに変更するだけです。

各ビットを順番に実行すると、何が起こるかがわかります。

_pax[/home/pax]> find / -type f -name ls
/usr/bin/ls

pax[/home/pax]> find / -type f -name ls | head -1
/usr/bin/ls

pax[/home/pax]> dirname "$(find / -type f -name ls | head -1)"
/usr/bin

pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"

pax[/usr/bin]> _
_
25
paxdiablo

以下の方が安全です。

cd -- "$(find / -name ls -type f -printf '%h' -quit)"

利点:

  • 二重ダッシュは、オプションとしてハイフンで始まるディレクトリ名の解釈を防ぎます(findはそのようなファイル名を生成しませんが、有害ではなく、同様の構造に必要な場合があります)
  • -name前に確認してください-typeチェック。後者にはstatが必要な場合があるため
  • dirnameは必要ないため、%h指定子はすでにディレクトリ名を出力します
  • -quit最初のファイルが見つかった後に検索を停止するため、headは必要ありません。これにより、改行を含むディレクトリ名でスクリプトが失敗します。
11
Philipp

見つけることを提案する人は誰もいません(これは巨大な木にとってはるかに速いです)?

zsh:

cd $(locate Zoo.txt|head -1)(:h)
cd ${$(locate Zoo.txt)[1]:h}
cd ${$(locate -r "/Zoo.txt$")[1]:h}   

or could be slow

cd **/Zoo.txt(:h)

bash:

cd $(dirname $(locate -l1 -r "/Zoo.txt$"))
5
zzapper

同様の質問に対する この回答 に基づいて、他の便利な選択肢は2つのコマンドを使用することです。1つ目はファイルを検索し、2つ目はそのディレクトリに移動します。

find ./ -name "champions.txt"
cd "$(dirname "$(!!)")"

どこ !!は、「前のコマンド」を意味する履歴拡張です。

3
Ricardo

findが見つけて各ディレクトリで操作を実行するすべてのファイルに繰り返しナビゲートしたい場合は、すでに与えられた回答を拡張します。

for i in $(find /path/to/search/root -name filename -type f)
do (
  cd $(dirname $(realpath $i));
  your_commands;
)
done
2
honkaboy

ファイルを見つけて別の場所に移動する場合は、findと-execを使用します。

find /path -type f -iname "mytext.txt" -exec mv "{}" /destination +;
1
ghostdog74
function fReturnFilepathOfContainingDirectory {
    #fReturnFilepathOfContainingDirectory_2012.0709.18:19
    #$1=File

    local vlFl
    local vlGwkdvlFl
    local vlItrtn
    local vlPrdct

    vlFl=$1
    vlGwkdvlFl=`echo $vlFl | gawk -F/ '{ $NF="" ; print $0 }'`
    for vlItrtn in `echo $vlGwkdvlFl` ;do
        vlPrdct=`echo $vlPrdct'/'$vlItrtn`
    done
    echo $vlPrdct

}
1
bkmfs

これを試して。私はこれを自分で使用するために作成しました。

cd ~
touch mycd
Sudo chmod +x mycd
nano mycd
cd $( ./mycd search_directory target_directory )"

if [ $1 == '--help' ]
 then
    echo -e "usage: cd \$( ./mycd \$1 \$2 )"
    echo -e "usage: cd \$( ./mycd search_directory target_directory )"
else
  find "$1"/ -name "$2" -type d -exec echo {} \; -quit
  fi
0
터터러

単純にこのように、これはエレガントではありませんか?

cdf yourfile.py

もちろん、最初に設定する必要がありますが、これを行う必要があります一度だけ

シェル初期化スクリプトとして使用するものは何でも、.bashrcまたは.zshrcに次の行を追加します。

source ~/bin/cdf.sh 

そして、このコードを、最初から作成する必要がある〜/ bin /cdf.shファイルに追加します。

#!/bin/bash

function cdf() {
    THEFILE=$1
    echo "cd into directory of ${THEFILE}"
    # For Mac, replace find with mdfind to get it a lot faster. And it does not need args ". -name" part.
    THEDIR=$(find . -name ${THEFILE} |head -1 |grep -Eo "/[ /._A-Za-z0-9\-]+/")
    cd ${THEDIR}
}
0
Ville Laitila

PATH内のプログラムの場合は、次のことができます。

cd "$(dirname "$(which ls)")"

またはBashで:

cd "$(dirname "$(type -P ls)")"

使用する外部実行可能ファイルが1つ少なくなります。

これは外部を使用しません:

dest=$(type -P ls); cd "${dest%/*}"

ファイルが1つの場所にのみある場合は、次のことを試すことができます。

cd "$(find ~/ -name [filename] -exec dirname {} \;)" && ...

_-exec_を使用して、returnを見つけるパス(_{}_プレースホルダーがある場所)でdirnameを呼び出すことができます。それはディレクトリを変更します。シェルがディレクトリを変更した後、次のコマンドを実行するためにダブルアンパサンド(_&&_)を追加することもできます。

例えば:
cd "$(find ~/ -name need_to_find_this.rb -exec dirname {} \;)" && Ruby need_to_find_this.rb

そのRubyファイルを探し、ディレクトリに移動して、そのフォルダ内から実行します。この例では、ファイル名は一意であり、何らかの理由でRubyスクリプトはそのディレクトリ内から実行する必要があります。ファイル名が一意でない場合、CDに渡される多くの場所を取得し、エラーを返します変更されませんディレクトリ

0
Gunga