2

У меня есть файл file_copy , который имеет:

>cat file_copy
file1
file2
file3

Я хочу скопировать file1 , file2 , file3 из /source в /dest . Один способ, которым я знаю, как это сделать, это просто сделать:

for line in `cat file_copy` ; do cp /source/$line /dest; done

Но я знаю, что есть лучший способ, возможно, с использованием find/xargs и / или awk и т.д. Каков предпочтительный способ сделать это?

2 ответа2

7

Лучший способ перебрать строки в файле - использовать while:

while read line; do cp /source/"$line" /dest/; done < file_copy

И хотя приведенное выше достаточно для большинства случаев, более надежное решение (хотя и редко необходимое):

while IFS= read -r line; do cp /source/"$line" /dest/; done < file_copy

IFS= предотвращает обрезку пробелов в начале и конце строки. -r предотвращает сброс обратной косой черты.


Относительно вашей оригинальной команды:

  • Там бесполезное использование кошки.

  • Вы не должны читать строки с for потому что это может привести к ошибкам, когда ваши строки содержат пробелы. На практике, если вы используете for чего-то еще, кроме циклического обхода имен файлов, генерируемых оболочкой (например, for f in *.csv), вы, вероятно, делаете что-то не так.

  • Вы также должны заключить свои переменные в кавычки, чтобы имена файлов с пробелами не разбивались на несколько аргументов.

3

Чтобы улучшить производительность, вы можете сделать следующее:

tar -cf -  'cat source.txt' | (cd $dest ; tar -xf -)

Сжатие файлов внутри вашего источника и извлечение их сделает работу быстрее, чем зацикливание!

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