почему это работает
for X in A* ; do cp $X/output.txt output/$X.txt ; done
но не это
cp A*/output.txt output/A*.txt
Для копирования файла output.txt из нескольких папок с именами A1, A2, A3, A4 и т. д. в объединенную папку с именем «output», присваивая каждому текстовому файлу имя папки, из которой он был получен.
решение1
Поскольку оболочка расширяет A*.txt
детальнесколькоpaths до того, как он будет передан вызываемой команде ( cp
в данном случае).
Это означает, что в первом случае, если у вас есть файлы с именами A1.txt, A2.txt, A3.txt и A4.txt и каталоги A1, A2, A3 и A4, каждый из которых содержит output.txt, он расширяется дочто-то вроде:
for X in A1.txt A2.txt A3.txt A4.txt ; do cp $X/output.txt output/$X.txt ; done
а во втором случае он расширяется до:
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A*.txt
где output/A*.txt
часть может или не может расширяться в зависимости от того, есть ли в каталоге что-то, output
соответствующее глобу. Если есть, то становится еще хуже, например:
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A8.txt output/A9.txt
Так как cp
при наличии нескольких исходных файлов требуется место назначениякаталогв конце концов, он не знает, как с этим справиться, и просто разводит руками, выдавая ошибку.
решение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 оператора, приведенных непосредственно выше, что вам и нужно.