Раньше у меня был смущающий круговой ответ здесь, но ответ Дениса напомнил мне, что я пропустил самую основную вещь. Итак, я удалил свой оригинальный ответ. Но так как никто не сказал эту самую основную вещь, я думаю, что это стоит поместить здесь.
Исходный вопрос: «У меня есть текстовый файл со списком разделенных пробелами имен файлов. Как я могу скопировать их в один целевой каталог». Сначала это может показаться сложным или сложным, потому что вы думаете, что вам нужно каким-то образом извлечь элементы из файла определенным образом. Тем не менее, когда оболочка обрабатывает командную строку, первое, что она делает, - разделяет список аргументов на токены и (это бит, который никто не сказал прямо) пробелами отдельные токены . (Новые строки также разделяют токены, поэтому тест Дуга Харриса со списком, разделенным новой строкой, дал тот же результат.) То есть оболочка ожидает и уже может обрабатывать разделенный пробелами список.
Поэтому все, что вам нужно сделать, это поместить разделенный пробелами список (который у вас уже есть) в нужное место в вашей команде. Ваша команда является некоторым вариантом этого:
cp file1 file2 file3...file# target
Единственная проблема заключается в том, что вы хотите получить список файлов с 1 по # из вашего текстового файла.
Как отмечает Деннис в своем комментарии, ваша первоначальная попытка ( cp
cat list.txt new_folder
) уже сработала Зачем? Поскольку внутренняя команда cat list.txt
сначала обрабатывается оболочкой и расширяется в нее file1 file2 file3...file#
, это именно то, что оболочка ожидает и хочет в этой части команды. Если это не сработало, либо (1) у вас была опечатка, либо (2) ваши имена файлов были как-то странными (в них были пробелы или другие необычные символы).
Причина того, что все ответы Денниса работают, заключается в том, что они предоставляют необходимый список файлов для 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
команда, которую вы хотели.
Я понимаю, что много бью эту (возможно, очень мертвую) лошадь, но думаю, это стоит того. Понимание того , как оболочка обрабатывает команду, может помочь вам написать ее лучше и значительно упростить. Это также покажет вам, где проблемы могут скрываться. В этом случае, например, мой первый вопрос к вам должен был быть о забавных именах файлов или возможной опечатке. Никакой акробатики не было необходимости.