J'ai un grand dossier d'images (en milliers) et j'ai une longue liste de fichiers, par nom de fichier exact, que je dois copier dans un autre dossier. Je souhaite savoir s’il est possible de sélectionner plusieurs fichiers spécifiques dans ce dossier, par leur nom, et de les copier dans un autre dossier à l’aide du terminal, sans les copier individuellement.
Vous pouvez y parvenir de plusieurs manières. Le plus simple que j'ai vu est d'utiliser ce qui suit.
cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination/
La syntaxe utilise la commande cp suivie du chemin d'accès au répertoire dans lequel se trouvent les fichiers souhaités. Tous les fichiers que vous souhaitez copier sont entourés de crochets et séparés par des virgules.
Assurez-vous de noter qu'il n'y a pas d'espace entre les fichiers. La dernière partie de la commande, /home/usr/destination/
, est le répertoire dans lequel vous souhaitez copier les fichiers.
ou si tous les fichiers ont le même préfixe mais des terminaisons différentes, vous pouvez faire quelque chose comme ceci:
cp /home/usr/dir/file{1..4} ./
Où fichier1, fichier2, fichier3 et fichier4 seraient copiés.
De la manière dont vous avez formulé la question, je pense que c’est ce que vous recherchez, mais il semble également que vous cherchiez peut-être une commande à lire dans une liste de fichiers et à les copier tous dans un répertoire donné. Si tel est le cas, faites le moi savoir et je modifierai ma réponse.
J'ai donc écrit un petit script python qui, selon moi, devrait permettre d'accomplir ce travail. Cependant, je ne suis pas sûr de votre niveau de connaissance de python (si je le connais bien). Je vais donc essayer d'expliquer comment utiliser ce script du mieux que je peux et s'il vous plaît posez autant de questions que vous le souhaitez. .
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))
Ce script devrait être relativement simple à utiliser. Tout d’abord, copiez le code ci-dessus dans le programme gedit (doit être pré-installé dans Ubuntu) ou dans n’importe quel autre éditeur de texte.
Une fois l’opération terminée, enregistrez le fichier sous le nom move.py dans votre répertoire personnel (il peut s’agir de n’importe quel répertoire, mais pour plus de commodité, utilisons simplement le répertoire personnel) ou ajoutez le répertoire dans lequel se trouve le fichier. à votre chemin. Puis cd
dans votre répertoire personnel (ou le répertoire dans lequel vous avez enregistré move.py) à partir du terminal et tapez la commande suivante:
python move.py /path/to/src/ /path/to/dst/ file.txt
Cela doit copier tous les fichiers répertoriés du répertoire source dans le répertoire de destination avec les doublons au format pic (1) .jpg, pic (2) .jpg, etc. fichier.txt devrait être un fichier qui répertorie toutes les images que vous souhaitez copier avec chaque entrée sur une ligne distincte.
Ce script ne doit en aucun cas affecter le répertoire source. Toutefois, assurez-vous de saisir les chemins d'accès corrects aux répertoires source et de destination. Le pire qui puisse arriver est de copier les fichiers dans le mauvais répertoire.
/
à la fin du chemin d'accès à la sourceIl me manque peut-être un détail de votre question, mais les réponses fournies semblent excessives. Si vous voulez une solution en ligne de commande et non un script, pourquoi pas:
cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...
La bonne chose à faire de cette façon est que vous pouvez compléter les noms de fichiers
Voici une solution pure bash. Il lit les noms de fichier d'un fichier d'entrée (un par ligne) et les copie, en renommant les doublons.
#!/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
Enregistrez ce script dans un dossier de votre $PATH
et appelez-le avec la liste des chemins en entrée:
auto_copy.sh < file_paths.txt
Vous pouvez également exécuter le tout en tant que commande du terminal:
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;
Selon la description de la question, ma compréhension est la suivante:
input.txt
Ainsi, on peut utiliser la commande suivante:
xargs -I % --arg-file=input.txt cp /path/to/Origin_dir/% /path/to/destination
Explication:
-I %
spécifie le symbole du fichier en cours de traitement à utiliser dans la commande--arg-file=input.txt
spécifie de prendre des arguments pour commander à partir de input.txt
cp /path/to/Origin_dir/% /path/to/destination/
effectuera la commande cp
en remplaçant le /path/to/Origin_dir/%
par le /path/to/Origin_dir/
et en indiquant le nom du fichier en cours de traitement.Exemple pratique:
$ 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