2013-10-01 6 views
7

私は、今日findでbashスクリプトの世界で冒険をしています。find -execのベースネームとフルパスの両方を使用する

私は、/ home/mine/Picturesのサブディレクトリにある任意のpngファイルを/ home/mine/pngcoppiesにコピーし、findと-execを使って "copy [basename]"という名前に変更したいと考えています。これは、同じexecコマンドでフルパス名とベース名の両方を使用する必要があります。私の問題は、私がベース名を得る方法を知らないということです。 (下記参照)

find /home/mine -iname "*.png" -exec cp {} /home/mine/pngcoppies/copy{what_do_I_enter_here?} \; 

注:上記の私がやっている実際にはありませんが、それは問題の根本的な例ですので、同じ目的を達成するためにいくつかの他の方法を使用して回避策は「wouldn本当にここには適用されません。問題は根本的にfind -execとbasenameの使用に関するものです。

ありがとうございます!

find /home/mine -iname "*.png" -printf "%P\n " | xargs -I % -n1 cp % /home/mine/pngcoppies/copy% 

答えて

9

あなたが検索を実行するときに何が起こっているかを確認するには、ちょうどset -xv
は-x入力します。プリントコマンドとその引数としてそれらが実行されている
-v:。。彼らが読み込まれるとプリントは、入力ラインシェル

ここで私が持っているものです。

find . -name "*.xml" -exec echo {} \; 

は、出力を与える:

./log.xml 
./svnLog.xml 

そして、私が試してみてください。

set -xv 
find . -name "*.xml" -exec echo {} \; 

私が手に:その後、

find . -name "*.xml" -exec echo {} \; 
+ find . -name '*.xml' -exec echo '{}' ';' 
./log.xml 
./svnLog.xml 

、代わりにlitteralの見つかったファイル名を渡すエコーを実行見つける:'{}'

しかしとき次のように{}に何かを追加してください:

ここで
find . -name "*.xml" -exec echo something{} \; 
+ find . -name '*.xml' -exec echo 'something{}' ';' 
something{} 
something{} 

エコーは私が持っている2つのxmlファイル用に2回実行されると'{}'これ以上は幹部のパラメータリストではありませんがあるので、交換するつもりはありません。見つかったファイルごとにecho 'something{}'が見つかりました。

はこれに対処するには、例えばのようなパラメータとして、それまでのファイル名をエコー通過を実行考えることができます。

sh -xvc 'echo sothing/$0' filename 

は、我々はすでに-x-vが何であるかを知っています。 -cは、それが(man sh

はとても結果は後に文字列からコマンドを取得することです:

sh -xvc 'echo somthing/$0' filename 
+ sh -xvc 'echo somthing/$0' filename 
echo somthing/$0 
+ echo somthing/filename 
sothing/filename 

は私が「」の間で「echo somthing/$0」を使用ので、$ 0が現在のシェルによって展開されません。

find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \; 

そして、我々が得る:

ので発見は、以下のようにフォーマットする必要があり、バックあなたの「問題」に到達するために);「」でそれを試してみて、あなたは$ 0 expantionが表示されます

find . -name "*.xml" -exec sh -xvc 'echo sothing/$0' {} \; 
+ find . -name '*.xml' -exec sh -xvc 'echo sothing/$0' '{}' ';' 
echo sothing/$0 
+ echo sothing/./log.xml 
sothing/./log.xml 
echo sothing/$0 
+ echo sothing/./svnLog.xml 
sothing/./svnLog.xml 

私たちが知っている見ることができるように は、検索はシェルcammand echo sothing/$0それ'{}'(検索で見つけたファイル名に置き換え)に渡すことを実行しようとしているので、私たちは希望echo sothing/./log.xml

を取得します

set +xv冗長モード を除去するために、我々は得ることができます。

find . -name "*.xml" -exec sh -c 'echo "cp $0 someWhereElse/$0"' {} \; 
cp ./log.xml someWhereElse/./log.xml 
cp ./svnLog.xml someWhereElse/./svnLog.xml 

ので、あなたのケースで、あなただけのサブシェルでコピーを実行する必要があります(execの後にshまたはbashかFAVORITシェルを追加)これは助けることができる

find /home/mine -iname "*.png" -exec sh -c 'cp $0 /home/mine/pngcoppies/copy/$0' {} \; 

希望)、そして私の英語のため恐れ入ります;そしてfindがそれにparapeterとしてファイル名を渡すことができます。

0

はこのような何かしてみてください 「 - execdir primaryは-execプライマリと同じですが、utilityがディレクトリtから実行される点が異なりますhatは現在のファイルを保持します。文字列 `` {}「」の代わりにファイル名が修飾されていない「

find /home/mine -iname "*.png" -execdir cp {} /home/mine/pngcoppies/copy{} \; 
+4

スプーンフィードをお願いします。申し訳ありませんが、これを検索のインスタンスにどのように適用できますか? – neanderslob

1

前にそのパスを取得するには

basename $your_full_path 

を使用するベース名を取得するために

4

男性から見つける:あなたはベース名

dirname $your_full_path 
関連する問題