Comment copier un fichier nommé commençant par un point?


26

J'essaie de copier tous les fichiers du répertoire A dans le répertoire B. Tous les fichiers du répertoire A commencent par un point, par exemple:

A/.a
A/.b
A/.c

que j'ai trouvé si j'utilise cp A/* B:, obtenez toujours une erreur:

cp: cannot stat 'A/*': no such file or directory

Il semble qu'il n'y a pas d' option pour cpque lspour les entrées poignée ouvertes avec un point, quelqu'un a idée de comment résoudre ce problème?

Réponses:


34

La raison en est que dans bash, *n'inclut pas les fichiers commençant par dot ( .).

Tu peux courir

cp A/.* B

Il vous avertira qu'il n'a pas copié .ou .., ni aucun sous-répertoire, mais c'est très bien.

Ou, si vous souhaitez copier des fichiers dot et des fichiers normaux ensemble, exécutez

cp A/.* A/* B

Vous pouvez également exécuter

shopt -s dotglob
cp A/* B

qui fonctionnera bash, mais pas sh.

Et si cela ne vous dérange pas de copier des sous-répertoires, c'est le plus simple:

cp -R A/ B

Astuce: si jamais des caractères génériques ne font pas ce que vous attendez, essayez de l'exécuter avec écho, par exemple

$ echo A/*
A/file1 A/file2

$ echo A/.*
A/. A/.. A/.hidden1 A/.hidden2

$ echo A/.* A/*
A/. A/.. A/.hidden1 A/.hidden2 A/file1 A/file2

$ shopt -s dotglob
$ echo A/*
A/file1 A/file2 A/.hidden1 A/.hidden2

C'est seulement un problème si vous utilisez -r. Sans -r, il sautera simplement les répertoires.
Mikel

Et l'exemple que je donne en utilisant -Rdevrait très bien fonctionner aussi. Si vous pensez que c'est faux, veuillez expliquer pourquoi.
Mikel

7

Si bash, vous pouvez définir dotglobavant de copier

shopt -s dotglob
cp A/* /destination

Ou un langage de programmation

$ ruby -rfileutils -e  'Dir[".*"].each {|x| FileUtils.copy(x,"/destination") if File.file?x}'

Si vous ne souhaitez pas définir dotglob,

cp A/.* /destination 2>/dev/null

L'utilisation de dotglob OP copiera également tous les fichiers non cachés, ce qui n'est pas ce qu'il veut.
peoro

@peoro, vous devriez relire la question. Tous les fichiers Asont masqués. Il veut juste copier ça.

7

Ce que vous cherchez, c'est plutôt:

cp A/.??* B/

Cela correspondra à tous les fichiers dot, mais pas "." ou "..". La plupart des solutions ci-dessus sont correctes tant que vous ne travaillez pas récursivement. Mais dès que vous voulez faire quelque chose comme:

cp -R A/.??* B/

Sans omettre "..", vous copiez tout du répertoire parent vers le bas, y compris les fichiers non dot.


1
Cela manquera les fichiers de points qui sont un seul caractère, comme .aou .x. Le modèle de globbing le plus court que j'ai trouvé qui correspond à tous les fichiers de points sauf .et ..est .[^.]*.
pavon du

2

J'ai juste essayé ce qui suit et ça marche, trouvez ...

cp A/.* B/

2
Cela passera également A/.et en A/..tant que paramètres à cp, ce qui pourrait être problématique dans le cas où OP doit également copier des répertoires (en utilisant cp -r)
peoro

2

Ce n'est pas cpla faute , c'est bash: bash se développe *dans tous les .fichiers non cachés (c'est-à-dire: ne commençant pas par ).

Bash se développera .*(ainsi A/.*, dans votre cas) avec tous les fichiers commençant par ., mais malheureusement, il inclut également .et ..(répertoires actuel et parent) que vous voudrez probablement ignorer. (Notez que d'autres shells, comme zsh, ne les incluraient pas, et IIRC bash aussi, après avoir défini certaines options).

Une solution simple pourrait être de supprimer .et ..de supprimer les fichiers correspondants .*, d'une manière (très) hacky comme celle-ci:

cp $( for F in A/.*; do echo $F | grep -v "^\.*$"; done ) B

ou celui-ci (probablement plus propre: il utilise findpour trouver les fichiers à copier):

cp $( find A -maxdepth 1 -mindepth 1 -name ".*" ) B

mais vous trouverez probablement des solutions plus propres.


pourquoi devriez-vous utiliser un for looppuis créer un grepprocessus supplémentaire juste pour faire un travail comme cp A/.*? cpignorera le "." et les répertoires "..".

1

S'ils commencent tous par un point, utilisez simplement A/.*:

[holt@Michaela test]$ cp A/* B
cp: cannot stat `A/*': No such file or directory

[holt@Michaela test]$ cp A/.* B
cp: omitting directory `A/.'
cp: omitting directory `A/..'
[holt@Michaela test]$ ls -al B
total 8
drwxrwxr-x. 2 holt holt 4096 2011-03-31 16:57 .
drwxrwxr-x. 4 holt holt 4096 2011-03-31 16:57 ..
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .a
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .b
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .c

J'espère que cela t'aides!


1

Vous pouvez utiliser ce script

IFS = $ '\ n'; pour agir dans $ (trouver A -d 1); faire cp -R "$ act" B; terminé


0

copie:

cp A/.* B

liste:

ls -l A/.*

liste des fichiers sans répertoires décroissants:

ls -ld A/.*

0

Vous devez exclure. et .. de la liste des fichiers passés à cp!

C'est sûr:

ls -1d A/.[a-zA-Z]* | xargs -i cp -rp {} B

0

C'est un vieux fil de discussion ... mais j'ai toujours pu copier tous les fichiers. Y compris les fichiers / dossiers commençant par "."

L'exemple copiera tous les fichiers et dossiers:

cp -aup /root/.* / backup / root /

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.