xargsを使用したディレクトリ内のファイルの移動

xargsを使用したディレクトリ内のファイルの移動

現在、ディレクトリ内のいくつかのフォルダを検索しています。私が望むのは、このディレクトリ内のすべてのファイルを別のディレクトリに移動することです。次のコマンドを使用しています。

find -maxdepth 1 -regex 'myRegexExpHere' | xargs -I file mv file/* Desktop/New\ folder/

ただし、期待どおりに「*」は xargs に拡張されず、代わりにすべてのフォルダから * というファイルを検索します。目標を達成するにはどうすればよいですか? (findの-execスイッチの代わりに)xargsだけを使用するアプローチを提案してください。主にxargsを使用する方が効率的だと読んだからです。

答え1

file一致するファイル名に置き換えられた後に実行されるシェルでワイルドカード拡張を実行する必要があります。したがって、からシェルを起動する必要がありますxargs

xargsexecを使用するよりも述語を使用する方が良いですfind。より簡単で、引用の問題は発生しません。

find -maxdepth 1 -regex 'myRegexExpHere' -exec sh -c 'mv "$0"/* Desktop/New\ folder/' {} \;

物事が複雑すぎる可能性があります。この簡単な使い方は、findほとんどのシェルで直接表現できます。 Kshには正規表現構文があります。

  • @(EXPR1|EXPR2)一致EXPR1するEXPR2
  • *(EXPR)0個以上の一致EXPR
  • +(EXPR)1つ以上の一致EXPR
  • ?(EXPR)0または1回一致EXPR

この構文は最初に実行するとbashでも動作し、最初に実行するとshopt -s extglobzshsetopt ksh_globでも動作します。その後利用できます

mv REGEX/* Desktop/New\ folder/

答え2

find必要ありませんが、なぜ再帰を使用するのですか?シェルを使用した正規表現のマッチング(ここではBashを想定し、必要に応じて修正してください):

for dir in */;do
    if [[ "$dir" =~ yourRegexHere ]];then
        mv -- "$dir"/* "Desktop/New folder/"
    fi
done

シェルの正規表現機能が要件と比較して弱すぎる場合、Perlよりも優れていません。

perl -e 'for(grep {/yourRegexHere/} glob "*/"){ 
             qx(mv -- "$_"/* "Desktop/New folder") 
         }'

関連情報