
Итак, у меня есть каталог, содержащий около 200 файлов следующих типов:
gre_6_c1_d34567.h3
gre_6_c1_d95543.h3
gre_6_c1_d42354.h3
gre_6_c1_d01452.h3
gre_6_c1_d23168.h3
gre_6_c1_435435.h3
Единственное различие между этими файлами — это номера после d
. У меня есть текстовый файл, который содержит только d
номера примерно 50 из этих файлов. Если бы я мог получить полное имя файла, я бы это сделал, но этот текстовый файл — вывод другого скрипта. Есть ли способ переместить эти файлы в другой каталог, используя номер d
из текстового файла?
решение1
Использование sed
e
флага:
sed 's|^\(.*\)$|mv gre_6_c1_\1.h3 newdir/|e' list.txt
Вышеперечисленные файлы будут перемещены для newdir/
изменения его соответствующим образом.
Я предполагаю, что в list.txt числа указаны ниже и разделены новой строкой:
d34567
d23168
Запустите это для подтверждения:
sed 's|^\(.*\)$|mv gre_6_c1_\1.h3 newdir/|' list.txt
решение2
С bash
4 вы можете загрузить массив с именами файлов, полученными из чисел в файле «драйвера», а затем использовать опцию -t
GNU, mv
чтобы переместить их в каталог одним махом. Примечание
#read contents of driver_file into an array arr using mapfile
mapfile -t arr <driver_file
#define prefix and suffix variables
prefix=gre_6_c1_d
suffix=.h3
#prefix each array element
arr=("${arr[@]/#/$prefix}")
#suffix each array element
arr=("${arr[@]/%/$suffix}")
#use GNU mv's -t facility to move files into newdir
mv -t newdir/ "${arr[@]}"
решение3
Считываем числа из файла по одному и выполняем перемещение (предполагается оболочка POSIX):
while read -r number; do
name="gre_6_c1_d$number.h3"
[ -f "$name" ] && mv -i "gre_6_c1_d$number.h3" /other/directory
done <number.list
Это также гарантирует, что число выдает имя файла, существующего в текущем каталоге, перед перемещением его в другой каталог. Команда mv -i
также запросит подтверждение перед перезаписью существующего файла.
Поскольку этот вопрос был помечен тегомxargs, мы могли бы попросить xargs
сгенерировать для нас список номеров:
xargs sh -c '
for number do
name="gre_6_c1_d$number.h3"
[ -f "$name" ] && mv "gre_6_c1_d$number.h3" /other/directory
done' sh <number.list
Это ничего не ускорит, но если вы xargs
предоставите -P
флаг для параллельного выполнения задач, вы можете получить небольшой прирост скорости:
xargs -P 5 -n 10 -h sh -c '
for number do
name="gre_6_c1_d$number.h3"
[ -f "$name" ] && mv "gre_6_c1_d$number.h3" /other/directory
done' sh <number.list
Это запустит максимум пять копий цикла параллельно и выдаст каждой партии максимум десять чисел.