У меня почти 4 файла lakhs (400 000) в папке с именем model, и из этой папки я выбрал несколько тысяч файлов, а их имена сохранены в id.txt. Теперь я хочу взять только файлы, перечисленные в id.txt из папки model, и скопировать их в другую папку с именем selected_ids.
Две папки находятся внутри того же каталога test, который содержит
model selected_ids id.txtid.txt содержит имена файлов один за другим, например:
ENSP00000290866.4_2.pdb.xz
385719215_2.pdb.xz
GENSCAN00000006392_3.pdb.xz
Папка модели содержит почти 3 файла lakh
ENSP00000290866.4_2.pdb.xz
385719215_2.pdb.xz
GENSCAN00000006392_3.pdb
* note: в папке некоторые файлы имеют расширение .pdb.xz и некоторые только .pdb
Я знаю, как скопировать один файл из одной папки в другую, как это
cp model/ENSP00000290866.4_2.pdb.xz selected_ids/
Но у меня есть тысячи и тысячи файлов для копирования за короткое время.
Может ли кто-нибудь дать эффективную команду для копирования файлов?
Предполагая, что в входном файле нет белых пробелов, вы можете просто использовать цикл for:
for f in $(<id.txt); do cp -v "model/$f" selected_ids/;done
Если у вас возникли проблемы с «\ r» в конце имен файлов (скорее всего, файл был сохранен в ОС семейства Windows), вам также необходимо обрезать переменную $f:
for f in $(<id.txt); do f=`echo $f|tr -d "\n\r"`; cp -v "model/$f" selected_ids/; done
Обратите внимание, что cp с опцией -v отображает текущий файл, который копируется, поэтому его легко проверить этот процесс пакетного копирования.
Используйте структуру while IFS= read -r variable; do... done < input.txt, чтобы читать файл по строкам и выполнять желаемый код в .... Это стандартный способ bash читать файл по очереди и действовать на него. С каталогом, как вы описали, это должно быть сделано так:
$ tree
.
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
├── GENSCAN00000006392_3.pdb.xz
├── id.txt
├── model
└── selected_ids
2 directories, 4 files
$ while IFS= read -r file; do cp "$file" selected_ids/"$file" ;done < id.txt
$ tree
.
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
├── GENSCAN00000006392_3.pdb.xz
├── id.txt
├── model
└── selected_ids
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
└── GENSCAN00000006392_3.pdb.xz
следующая команда:
cd /path/to/model
$ xargs -d '\n' -a /path/to/id.txt cp -t /path/to/selected_ids
это будет читать имя файла, сохраненное в id.txt, и копировать в каталог selected_ids.
Предполагая, что в входном файле нет белых пробелов, вы можете просто использовать цикл for:
for f in $(<id.txt); do cp -v "model/$f" selected_ids/;done
Если у вас возникли проблемы с «\ r» в конце имен файлов (скорее всего, файл был сохранен в ОС семейства Windows), вам также необходимо обрезать переменную $f:
for f in $(<id.txt); do f=`echo $f|tr -d "\n\r"`; cp -v "model/$f" selected_ids/; done
Обратите внимание, что cp с опцией -v отображает текущий файл, который копируется, поэтому его легко проверить этот процесс пакетного копирования.
Используйте структуру while IFS= read -r variable; do... done < input.txt, чтобы читать файл по строкам и выполнять желаемый код в .... Это стандартный способ bash читать файл по очереди и действовать на него. С каталогом, как вы описали, это должно быть сделано так:
$ tree
.
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
├── GENSCAN00000006392_3.pdb.xz
├── id.txt
├── model
└── selected_ids
2 directories, 4 files
$ while IFS= read -r file; do cp "$file" selected_ids/"$file" ;done < id.txt
$ tree
.
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
├── GENSCAN00000006392_3.pdb.xz
├── id.txt
├── model
└── selected_ids
├── 385719215_2.pdb.xz
├── ENSP00000290866.4_2.pdb.xz
└── GENSCAN00000006392_3.pdb.xz
следующая команда:
cd /path/to/model
$ xargs -d '\n' -a /path/to/id.txt cp -t /path/to/selected_ids
это будет читать имя файла, сохраненное в id.txt, и копировать в каталог selected_ids.