このコマンドのdirnameとbasenameは何ですか?

このコマンドのdirnameとbasenameは何ですか?

このコマンドを使用すると、ディレクトリとサブディレクトリのアーカイブを再帰的に解凍して、現在の作業ディレクトリの構造を保存できます。

find ../backUp/ -name "*.zip" | 
  xargs -P 5 -I fileName sh -c '
    unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"
  '

ただし、実行すると、解凍されたすべてのフォルダが元のディレクトリに残ります。 Bash環境でbasenameとdirnameをハードコードできますか?

例を追加:

/backUp/pic1/1.zip
/backUp/pic2/2.zip
/backUp/pic3/3.zip

Goal:    
/new/pic1/1-1.png 
/new/pic1/1-2.png    
/new/pic2/2-1.png
/new/pic2/2-2.png    
/new/pic3/3-1.png

答え1

検索オプションを使用する必要があります-execdir。その後、cd一致するファイル(「* .zip」)を含む各ディレクトリに到達し、指定したコマンドを実行し、その特定のディレクトリの一致するファイル名をコマンドの引数として渡します。

たとえば、

find . -name '*.zip' -execdir sh -c 'for f; do unzip -o "$f"; done' find-sh {} +

注:asコマンドを使用しているので、sh -cダミー引数を最初の(0番目)引数として渡す必要があります。これはカーネルプロセステーブルのプロセス名になります(ここではfind-sh名前として使用します)。残りのパラメーターは{}ファイル名です。これらの項目は、、、、などsh -cの一般的な方法でスクリプトからアクセスできます。この例では、その項目を繰り返します。$1$2$3$@$*for f; do ... ; donefor f in "$@"; do ... ; done

ちなみに、どのように動作するかを解凍echoする代わりに使用できます。たとえば、次のコマンドは、1つ以上の.zipファイルを含む各ディレクトリの名前と、その後にコロンとそのディレクトリの.zipファイルのリストを印刷します。ディレクトリごとに1行ずつ出力します。

find . -name "*.zip" -execdir sh -c 'echo "$PWD:" "$@"' find-sh {} +

関連情報