2016-05-29 2 views
1

Voici ce que je suis en train de faire - prendre un répertoire source:Comment copier via wild card dans linux/bash?

/xyz/2/file.txt 
/xyz/2/crapfile.txt 
/xyz/3/file.txt 
/xyz/3/crapfile.txt 

et je veux copier fichier.txt dans le répertoire suivant:

/z/2 
/z/3 

J'aime faire quelque chose comme ça , mais cela ne fonctionne pas:

cp -r /xyz/*/file.txt /z/*/ 

pour éviter les choses de copie séparément - que je peux faire ce qui suit:

cp -r /xyz/2/file.txt /z/2/ 
cp -r /xyz/3/file.txt /z/3/ 
+0

est 2 et 3 les seuls dossiers sous xyz /? aussi, êtes-vous limité à cp .. ou vous pouvez simplement utiliser "rsync"? – zee

Répondre

1

Cette commande copie de xyz à z excluant tous les fichiers nommés crapfile.txt:

rsync -a --exclude=crapfile.txt xyz/ z 

Avec l'-v l'option (bavard), nous pouvons voir ses travaux en cours:

$ rsync -va --exclude=crapfile.txt xyz/ z 
sending incremental file list 
./ 
2/ 
2/file.txt 
3/ 
3/file.txt 

Comme vous pouvez voir, file.txt a été copié mais crapfile.txt a été ignoré.

rsync est un utilitaire très puissant avec beaucoup d'options. Pour plus d'informations, voir man rsync ou l'un des rsync tutorials sur le Web.

0

Utilisez une boucle for avec un ls:

for I in `ls /xyz`; do mkdir /z/$I; cp -r /xyz/$I/file.txt /z/$I/ ; done 

(Ou si/z/2 et/z/3 est déjà existant sauter mkdir!)

+0

[Ne pas analyser 'ls'] (http://mywiki.wooledge.org/ParsingLs) – anishsane

+0

... _then sauter mkdir_: Vous pouvez utiliser' mkdir -p' pour cela ... – anishsane

0

Au lieu d'utiliser une carte sauvage , vous pourriez faire quelque chose de similaire à:

for x in $(ls /xyz) 
do 
mkdir /z/$x 
cp /xyz/$x/file.txt /z/$x/ 
done 

Si les dossiers sous z n'existent déjà, sinon enlever le mkdir li ne ci-dessus

+0

[Ne pas analyser 'ls'] (http://mywiki.wooledge.org/ParsingLs) – anishsane

0

Sur la base de ma compréhension de la question, le soufflet doit le faire:

[za]$ cp -rv xyz/{dir_1/,dir_2}/* target_dir/ 
`xyz/dir_1//file3_dir1.txt' -> `target_dir/file3_dir1.txt' 
`xyz/dir_1//file4_dir1.txt' -> `target_dir/file4_dir1.txt' 
`xyz/dir_2/file1.txt' -> `target_dir/file1.txt' 
`xyz/dir_2/file2.txt' -> `target_dir/file2.txt' 
`xyz/dir_2/file3.txt' -> `target_dir/file3.txt' 
`xyz/dir_2/file4.txt' -> `target_dir/file4.txt' 

[za]$ cp -rv xyz/{dir_1/,dir_2}/*.txt target_dir/ 
`xyz/dir_1//file3_dir1.txt' -> `target_dir/file3_dir1.txt' 
`xyz/dir_1//file4_dir1.txt' -> `target_dir/file4_dir1.txt' 
`xyz/dir_2/file1.txt' -> `target_dir/file1.txt' 
`xyz/dir_2/file2.txt' -> `target_dir/file2.txt' 
`xyz/dir_2/file3.txt' -> `target_dir/file3.txt' 
`xyz/dir_2/file4.txt' -> `target_dir/file4.txt' 



other ways depending on what you are trying to achive. 

1) 
[za temp_dir]$ cp -rv xyz/* target_dir/ 
`xyz/dir_1' -> `target_dir/dir_1' 
`xyz/dir_1/file3_dir1.txt' -> `target_dir/dir_1/file3_dir1.txt' 
`xyz/dir_1/file4_dir1.txt' -> `target_dir/dir_1/file4_dir1.txt' 
`xyz/dir_2' -> `target_dir/dir_2' 
`xyz/dir_2/file1.txt' -> `target_dir/dir_2/file1.txt' 
`xyz/dir_2/file2.txt' -> `target_dir/dir_2/file2.txt' 
`xyz/dir_2/file3.txt' -> `target_dir/dir_2/file3.txt' 
`xyz/dir_2/file4.txt' -> `target_dir/dir_2/file4.txt' 

2) 
[za temp_dir]$ for x in $(find . -type f) ; do cp -v $x target_dir/ ; done 
`./target_dir/dir_1/file3_dir1.txt' -> `target_dir/file3_dir1.txt' 
`./target_dir/dir_1/file4_dir1.txt' -> `target_dir/file4_dir1.txt' 
`./target_dir/dir_2/file1.txt' -> `target_dir/file1.txt' 
`./target_dir/dir_2/file2.txt' -> `target_dir/file2.txt' 
`./target_dir/dir_2/file3.txt' -> `target_dir/file3.txt' 
`./target_dir/dir_2/file4.txt' -> `target_dir/file4.txt' 
`./xyz/dir_1/file3_dir1.txt' -> `target_dir/file3_dir1.txt' 
`./xyz/dir_1/file4_dir1.txt' -> `target_dir/file4_dir1.txt' 
`./xyz/dir_2/file1.txt' -> `target_dir/file1.txt' 
`./xyz/dir_2/file2.txt' -> `target_dir/file2.txt' 
`./xyz/dir_2/file3.txt' -> `target_dir/file3.txt' 
`./xyz/dir_2/file4.txt' -> `target_dir/file4.txt' 


3)  
[za temp_dir]$ rsync -rav xyz/* target_dir/ 
sending incremental file list 
dir_1/ 
dir_1/file3_dir1.txt 
dir_1/file4_dir1.txt 
dir_2/ 
dir_2/file1.txt 
dir_2/file2.txt 
dir_2/file3.txt 
dir_2/file4.txt 

sent 414 bytes received 134 bytes 1096.00 bytes/sec 
total size is 0 speedup is 0.00 
[za temp_dir]$ 


4) 
[za]$ find xyz/ | while read ; do cp -v $REPLY target_dir/ ; done 
cp: omitting directory `xyz/' 
cp: omitting directory `xyz/dir_1' 
`xyz/dir_1/file3_dir1.txt' -> `target_dir/file3_dir1.txt' 
`xyz/dir_1/file4_dir1.txt' -> `target_dir/file4_dir1.txt' 
cp: omitting directory `xyz/dir_2' 
`xyz/dir_2/file1.txt' -> `target_dir/file1.txt' 
`xyz/dir_2/file2.txt' -> `target_dir/file2.txt' 
`xyz/dir_2/file3.txt' -> `target_dir/file3.txt' 
`xyz/dir_2/file4.txt' -> `target_dir/file4.txt' 


sent 414 bytes received 134 bytes 1096.00 bytes/sec 
total size is 0 speedup is 0.00 
+0

Vous ne devriez [jamais lancer une boucle sur les résultats' find' ou 'ls'] (http://mywiki.wooledge.org/ParsingLs). 'pour x dans $ (ls/find ...)' est strict non non. 'ls/trouver | tandis que read -r x' est légèrement meilleur et peut éventuellement fonctionner pour des cas d'utilisation courants. Mais le meilleur moyen dans ce cas est d'utiliser l'option '-exec' de find ou d'utiliser' find -print0 | alors lisez la boucle -r -d '' x'. – anishsane