なぜこれが機能するのか
for X in A* ; do cp $X/output.txt output/$X.txt ; done
しかし、これは違う
cp A*/output.txt output/A*.txt
A1、A2、A3、A4 などという複数のフォルダーから output.txt ファイルを「output」という結合フォルダーにコピーし、各テキスト ファイルに元のフォルダーの名前を付与します。
答え1
シェルがA*.txt
部分を拡張するため複数呼び出されるコマンドに渡される前にパスを指定します (cp
この場合は)。
つまり、最初のケースでは、A1.txt、A2.txt、A3.txt、A4.txtという名前のファイルがあり、それぞれoutput.txtを含むディレクトリA1、A2、A3、A4がある場合、次のように展開されます。何かのようなもの:
for X in A1.txt A2.txt A3.txt A4.txt ; do cp $X/output.txt output/$X.txt ; done
2 番目のケースでは、次のように展開されます。
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A*.txt
このoutput/A*.txt
部分は、ディレクトリ内に glob に一致するものが存在するかどうかによって拡張される場合とされない場合output
があります。存在する場合は、次のようにさらに悪化します。
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A8.txt output/A9.txt
cp
複数のソースファイルが与えられた場合、宛先ファイルが必要ですディレクトリ結局、これをどう処理したらよいか分からず、単に手を上げて代わりにエラーを返します。
答え2
その理由は、 に2つ以上の引数がある場合cp
、最後の引数がしなければならないディレクトリになります。cp マニュアルページ状態:
概要
cp [オプション]... [-T] ソース 宛先
cp [オプション]... ソース... ディレクトリ
cp [オプション]... -t ディレクトリソース...
説明
SOURCE を DEST にコピーするか、複数の SOURCE を DIRECTORY にコピーします。
あなたが書いたコマンドは、
cp file1 file2 file3 file4
意図されていたのは
cp file1 file3; cp file2 file4
しかし、上記の理由により、そうはなりません。代わりに、for ループは、まさに上記の 2 つのステートメントを生成します。これが、実際に必要なことです。