私は以前ここで恥ずかしいほどラウンドアラウンドな回答をしていましたが、デニスの回答は私が最も基本的なものを見逃したことを思い出させました。そこで、元の回答を削除しました。しかし、この非常に基本的なことを誰も言っていないので、ここに置く価値があると思います。
元の質問は、「スペースで区切られたファイル名のリストを含むテキストファイルがあります。それらを1つのターゲットディレクトリにコピーするにはどうすればよいですか」です。どういうわけか、特定の方法でファイルからアイテムを抽出する必要があると思うので、これは最初は難しいか複雑に見えるかもしれません。ただし、シェルがコマンドラインを処理するとき、最初に行うことは、引数リストをトークンに分離し、(ここでは誰も明言していないビットが)トークンを分離します。(改行もトークンを分離するため、改行で区切られたリストを使用したダグ・ハリスのテストは同じ結果になりました。)つまり、シェルはスペースで区切られたリストを予期し、すでに処理できます。
したがって、ここで行う必要があるのは、スペースで区切られたリスト(既に持っているもの)をコマンドの適切な場所に置くことだけです。あなたのコマンドはこれに関するいくつかのバリエーションです:
cp file1 file2 file3...file# target
唯一の欠点は、テキストファイルからファイル1〜#のリストを取得することです。
Dennisがコメントで指摘しているように、元の試み(cp
cat list.txt new_folder
)はすでに機能しているはずです。どうして?内部コマンドcat list.txt
は最初にシェルによって処理され、に展開されるためfile1 file2 file3...file#
、これはシェルがコマンドのその部分で期待し、望んでいることとまったく同じです。うまくいかなかった場合は、(1)入力ミスがあるか、(2)ファイル名が何らかの形で奇妙でした(スペースまたはその他の異常な文字がありました)。
Dennisのすべての回答が機能する理由は、作業するために必要なファイルのリストを提供し、cp
コマンド全体でそのリストをそのリストに配置するためです。繰り返しますが、コマンド自体の構造は次のとおりです。
cp list-of-files target_directory
このバージョンでは、これらすべてがどのように組み合わされるかを簡単に確認できます。
cp $(<list.txt) new_folder
$()
これにより、シェルは括弧内のコマンドを実行し、大きな行のそのポイントで出力を置き換えます。次に、シェルは行全体を実行します。ちなみに、$()
あなたはすでにバックティックス( `)で行っていたことのより新しいバージョンです。次<
は、ファイルのリダイレクト演算子です。シェルに内容list.txt
を標準入力にダンプするよう指示します。$()
ビットが最初に処理されるため、段階的に次のようになります。
cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
明らかに、ステップ2は単にcp
必要な通常のコマンドです。
私はこの(おそらく非常に死んだ)馬をたくさんlotっていることに気づきましたが、やりがいがあると思います。シェルがコマンドを処理する方法を正確に理解することは、コマンドをより適切に記述し、大幅に簡素化するのに役立ちます。また、問題が隠れている可能性が高い場所も示します。この場合、たとえば、私の最初の質問は、おかしなファイル名や入力ミスの可能性についてでした。アクロバットは必要ありませんでした。