У меня есть большая папка с изображениями (тысячи), и у меня есть длинный список файлов с точным именем, которые мне нужно скопировать в другую папку. Я хочу знать, есть ли способ выбрать несколько определенных файлов из этой папки по имени и скопировать их в другую папку, используя терминал, не копируя их по отдельности?
Возможно, мне не хватает детали вашего вопроса, но приведенные ответы кажутся чрезмерными. Если вам нужно решение из командной строки, а не сценарий, почему бы и нет:
cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...
Хорошая вещь в том, чтобы сделать это таким образом, заключается в том, что вы можете заполнить имена файлов табуляцией
Согласно описанию вопроса, насколько я понимаю:
input.txt
Таким образом, можно использовать следующую команду:
xargs -I % --arg-file=input.txt cp /path/to/origin_dir/% /path/to/destination
Объяснение:
-I%
указывает символ для текущего обрабатываемого файла, который будет использоваться внутри команды - arg-file = input.txt
указывает, что аргументы команды принимаются из input.txt
cp / path / to / origin_dir /% / path / to / destination /
выполнит команду cp
с заменой / path / to / origin_dir /%
на / path / to / origin_dir /
и имя текущего обрабатываемого файла. Практический пример:
$ cat input.txt
file2.txt
file1.txt
file3.txt
$ ls ./docs
file1.txt file2.txt file3.txt
$ xargs -I % --arg-file=input.txt cp ./docs/% ./docs_destination/
$ ls ./docs_destination/
file1.txt file2.txt file3.txt
Вот чистое решение для bash. Он будет читать имена файлов из входного файла (по одному в каждой строке) и копировать каждое из них, переименовывая дубликаты.
#!/usr/bin/env bash
## The destination folder where your files will
## be copied to.
dest="bar";
## For each file path in your input file
while read path; do
## $target is the name of the file, removing the path.
## For example, given /foo/bar.txt, the $target will be bar.txt.
target=$(basename "$path");
## Counter for duplicate files
c="";
## Since $c is empty, this will check if the
## file exists in target.
while [[ -e "$dest"/"$target"$c ]]; do
echo "$target exists";
## If the target exists, add 1 to the value of $c
## and check if a file called $target$c (for example, bar.txt1)
## exists. This loop will continue until $c has a value
## such that there is no file called $target$c in the directory.
let c++;
target="$target"$c;
done;
## We now have everything we need, so lets copy.
cp "$path" "$dest"/"$target";
done
Сохраните этот сценарий в папке в $ PATH
и вызовите его со списком путей в качестве входных:
auto_copy.sh < file_paths.txt
Вы также можете запустить все это как команду с терминала:
while read path; do
target=$(basename "$path");
c="";
while [[ -e bar/"$target"$c ]]; do
echo "$target exists";
let c++;
target="$target"$c;
done;
cp "$file" bar/"$target";
done < file_names;
Есть несколько способов добиться этого. Самым простым, что я видел, является использование следующего.
cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination/
Синтаксис использует команду cp, за которой следует путь к каталогу, в котором находятся нужные файлы, со всеми файлами, которые вы хотите скопировать, заключенными в квадратные скобки и разделенными запятыми.
Обратите внимание на то, что между файлами нет пробелов. Последняя часть команды / home / usr / destination /
- это каталог, в который вы хотите скопировать файлы.
или, если все файлы имеют одинаковый префикс, но разные окончания, вы можете сделайте что-нибудь вроде этого:
cp /home/usr/dir/file{1..4} ./
Где будут скопированы файлы1, файл2, файл3 и файл4.
Судя по тому, как вы сформулировали вопрос, я считаю, что это именно то, что вы ищете, но также похоже, что вы, возможно, ищете команда для чтения из списка файлов и копирования их всех в определенный каталог. Если это так, дайте мне знать, и я отредактирую свой ответ.
Итак, я написал небольшой скрипт на Python, который, как мне кажется, должен выполнить свою работу. Однако я не уверен, насколько хорошо вы разбираетесь в python (если вообще разбираетесь), поэтому я постараюсь объяснить, как использовать этот скрипт, как можно лучше, и, пожалуйста, задайте столько вопросов, сколько вам нужно.
import os,sys,shutil
### copies a list of files from source. handles duplicates.
def rename(file_name, dst, num=1):
#splits file name to add number distinction
(file_prefix, exstension) = os.path.splitext(file_name)
renamed = "%s(%d)%s" % (file_prefix,num,exstension)
#checks if renamed file exists. Renames file if it does exist.
if os.path.exists(dst + renamed):
return rename(file_name, dst, num + 1)
else:
return renamed
def copy_files(src,dst,file_list):
for files in file_list:
src_file_path = src + files
dst_file_path = dst + files
if os.path.exists(dst_file_path):
new_file_name = rename(files, dst)
dst_file_path = dst + new_file_name
print "Copying: " + dst_file_path
try:
shutil.copyfile(src_file_path,dst_file_path)
except IOError:
print src_file_path + " does not exist"
raw_input("Please, press enter to continue.")
def read_file(file_name):
f = open(file_name)
#reads each line of file (f), strips out extra whitespace and
#returns list with each line of the file being an element of the list
content = [x.strip() for x in f.readlines()]
f.close()
return content
src = sys.argv[1]
dst = sys.argv[2]
file_with_list = sys.argv[3]
copy_files(src,dst,read_file(file_with_list))
Этот скрипт должен быть относительно простым в использовании. Прежде всего, скопируйте приведенный выше код в программу gedit (которая должна быть предварительно установлена в Ubuntu) или любой другой текстовый редактор.
После этого сохраните файл как move.py у себя дома. каталог (это может быть любой каталог, но для простоты инструкций позволяет просто использовать домашний каталог) или добавить каталог, в котором содержится файл, в ваш PATH. Затем cd
в свой домашний каталог (или любой другой каталог, в котором вы сохранили файл move.py) с терминала и введите следующую команду:
python move.py /path/to/src/ /path/to/dst/ file.txt
Это должно скопировать все файлы, перечисленные из исходного каталога, в каталог назначения с дубликатами в формате pic (1) .jpg, pic (2) .jpg и так далее. file.txt должен быть файлом, в котором перечислены все изображения, которые вы хотите скопировать, с каждой записью в отдельной строке.
Ни в коем случае этот сценарий не должен влиять на исходный каталог, однако просто убедитесь, что чтобы ввести правильные пути к исходному и целевому каталогам, и худшее, что может случиться, - это скопировать файлы в неправильный каталог.
/
на обоих путях к источник После того, как я нажал несколько раз, мое решение - небольшой скрипт для cp
всего в папке, чтобы он выглядел точно так, как мне нужен архив (папки и все), затем cd
и zip -r ../
и я получу .zip там, где я хочу, с именно той структурой, которую я хочу .
Другой способ - использовать несколько команд zip, например:
cd <parent_of_directory> && zip -r /path/to/archive.zip directory/* && \
cd <folder_with_files> && zip /path/to/archive.zip addfile1 addfile2 addfile2;
Примеры любезно предоставлены: https://wpguru.co.uk/2018/12/how-to-add-files-to-an -existing-zip-archive-on-macos-and-linux /