Почему бы не использовать вместо этого rsync
? Это сделано для задания!
rsync -uan --progress --exclude=".*" <source> <destination>
Выше перечислены все файлы, которые нужно заархивировать без фактического копирования. Проверьте, что список правильный, затем запустите его снова, удалив опцию n
, чтобы скопировать файлы (вы также можете удалить --progress
для более тихой работы).
Для расширения, вышеприведенные опции:-
u
- 'update' - только копируйте более новые файлы.
a
- 'archive'
n
- 'dry-run' - не копируйте, а просто перечислите, что это будет делать.
--progress
- показываем ход копирования
--exclude=".*"
- исключаем файлы, которые начинаются с точки
Не нужно ни awk, ни sed, так как ваш filelist.txt
уже находится в идеальном формате.
Несколько вещей заранее... Я предполагаю, что в именах файлов нет пробелов, и что пробел разделяет имена двух файлов в каждой строке. Также я предполагаю, что filelist.txt
завершает EOL перед EOF.
Конечно, сделайте резервную копию каталога перед выполнением этой команды.
#!/usr/bin/env bash
cd /path/to/pdb_files
while read -r line; do
mv $line
done < /path/to/filelist.txt
во время чтения -r строки; do
: Это выполняется через каждую строку файла, помещая каждую строку в переменную $line
. mv $line
: Так как каждая строка содержит два имени файла, разделенных пробелом, мы можем передавать аргументы напрямую в mv
, т.е. сразу же переносить файлы с первого имени файла на второе. Я только что перечитал ваш вопрос. Я интерпретировал его так, как вы хотите переименовать файлы с (например) 1.pdb
на Bioimage_23335989_Data_22317866_22317867_20140723_1002.pdb
. Я не уверен, что вы хотели, чтобы все было наоборот. Если да, то вместо этого будет работать следующий скрипт.
#!/usr/bin/env bash
cd /path/to/pdb_files
while read -r line; do
mv $(awk '{print $2, $1}' <<<$line)
done < /path/to/filelist.txt
mv $(awk '{print $2, $1}}' <<<$line)
: Читайте из $line
и распечатайте второе поле, за которым следует первое. Передайте эти два имени файлов в качестве параметров в mv
.