1

почему это работает

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", дающую каждому текстовому файлу имя папки, из которой он получен.

2 ответа2

5

Поскольку оболочка расширяет часть A*.txt до нескольких путей, прежде чем она будет передана вызываемой команде (в данном случае 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 при задании нескольких исходных файлов хочет каталог назначения в конце, он не знает, как с этим справиться, и просто подбрасывает руки и вместо этого выдает ошибку.

0

Причина в том, что если cp содержит более двух аргументов, последний должен быть каталогом. Страница man cp гласит:

конспект

cp [ВАРИАНТ] ... [-T] ИСТОЧНИК DEST

cp [ВАРИАНТ] ... ИСТОЧНИК... КАТАЛОГ

cp [ОПЦИЯ] ... -t ИСТОЧНИК КАТАЛОГА ...

Описание

Скопируйте ИСТОЧНИК в DEST или несколько ИСТОЧНИКОВ в DIRECTORY.

Команда, которую вы написали,

  cp file1 file2 file3 file4

должен был означать

 cp file1 file3; cp file2 file4

но это не так, по вышеуказанной причине. Вместо этого цикл for генерирует ровно 2 оператора, приведенные выше, что вы действительно хотите.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .