Раньше у меня был смущающий круговой ответ здесь, но ответ Дениса напомнил мне, что я пропустил самую основную вещь. Итак, я удалил свой оригинальный ответ. Но так как никто не сказал эту самую основную вещь, я думаю, что это стоит поместить здесь.
Исходный вопрос: «У меня есть текстовый файл со списком разделенных пробелами имен файлов. Как я могу скопировать их в один целевой каталог. »Сначала это может показаться сложным или сложным, потому что вы думаете, что вы должны каким-то образом извлечь элементы из файла определенным образом. Тем не менее, когда оболочка обрабатывает командную строку, первое, что она делает, - разделяет список аргументов на токены и (это бит, который никто не сказал прямо) пробелами отдельные токены. (Новые строки также разделяют токены, поэтому тест Дуга Харриса со списком, разделенным новой строкой, дал тот же результат.) То есть оболочка ожидает и может уже обрабатывать разделенный пробелами список.
Поэтому все, что вам нужно сделать, это поместить разделенный пробелами список (который у вас уже есть) в нужное место в вашей команде. Ваша команда является некоторым вариантом этого:
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
вы хотели.
Я понимаю, что много бью эту (возможно, очень мертвую) лошадь, но думаю, это стоит того. Понимание того , как оболочка обрабатывает команду, может помочь вам написать ее лучше и значительно упростить. Он также покажет вам, где могут скрываться проблемы. В этом случае, например, мой первый вопрос к вам должен был быть о забавных именах файлов или возможной опечатке. Никакой акробатики не было необходимости.