web-dev-qa-db-ja.com

find(1)の-execパラメーターのサブシェル引数

なぜしないのですか

_find . -type f -exec echo $(file={}; echo ${file:0:5}) \;
_

これが機能する間、ファイルの最初の5文字を​​指定します。

_find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;
_

背景

画像でいっぱいのツリーをサムネイルにバッチ変換しようとしていますが、ファイル名の末尾の拡張子の前に「_thumb」を追加して、その場で名前を変更したいと思います。この名前変更プロセスは、1つのファイルで簡単です。

_file='I am a picture.jpg'
mv \"$file\" \"${file%\.*}_thumb.${file##*\.}\"
_

(2行目は_mv "I am a picture.jpg" "I am a picture_thumb.jpg"_に展開されます)

しかし、このコマンドを find(1) の_-exec_パラメーターにカプセル化しようとすると、findで指定されたファイル名を操作できません(例は簡略化されています)。

_find . -type f -exec ${{}:0:5}) \;
_

与える

_bash: ${{}:0:5}: bad substitution
_

サブシェルを使用して、もう少し詳しく説明します。

_find . -type f -exec echo $(file={}; echo ${file:0:5}) \;
_

これはファイル名をエコーし​​ますが、何らかの理由で文字列操作を実行しません。

私はついに解決策を見つけました this SO post

_find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;
_

しかし、$(...)構文が機能しないのになぜこれが機能するのか理解できません。

7
Tim

execはそれが言うことをします:exec()を使用します。 (_-exec bash ..._)に指示されない限り、シェルは含まれません。指示された場合、stillを維持するには、一重引用符が必要です。変数の補間を解釈することからのインタラクティブなシェル。 (シェルは魔法ではなく、あなたがそれらを他の何かによって補間されることを意図したことを知りません。)


たとえば、次のコマンドを使用する場合:

検索。 -type f -exec echo $(file = {}; echo $ {file:0:5}) \; 

シェルfirst$(file={}; echo ${file:0:5})を実行してプロセス置換を実行します。これは単に_{}_を出力し、thenは最後のコマンドを実行します。

検索。 -type f -exec echo {} \; 
7
geekosaur