web-dev-qa-db-fra.com

Comment utilisez-vous des expressions régulières avec la commande cp sous Linux?

J'essaie de copier uniquement un sous-ensemble de fichiers d'un répertoire à un autre en utilisant cp, mais je suis accueilli avec le message cp: cannot stat [^\.php]': No such file or directory. Est-il possible d'utiliser des expressions régulières uniquement à l'aide de la commande cp?

21
PeanutsMonkey

Non.

La commande cp ne possède pas la capacité de traiter aucun de ses arguments en tant qu'expressions régulières. Même les caractères génériques ne sont pas gérés par lui (ou la plupart des exécutables); ils sont plutôt traités par le shell.

cp test/* test2/ est en fait développé par bash, et tout ce que cp voit vraiment dans ses arguments est cp test/file1 test/file2 test/file3 test2/ (ou ce qui est approprié en fonction du contenu réel de test/).

De plus, je ne pense pas que votre expression, [^\.php], correspondra à ce que vous souhaitez (elle ne correspond pas uniquement aux fichiers contenant .php).

Vous voudrez probablement examiner l'utilitaire find pour filtrer une liste de fichiers en fonction d'une expression régulière, puis utiliser xargs pour appliquer la liste de fichiers renvoyée à la commande cp (supposons que find n'a pas de gestionnaire intégré pour la copie de fichiers Je ne connais pas très bien l’outil).

Vous pourriez essayer:

find . ! -iregex ".*\.php.*" -exec cp {} /destination/folder/ \;

Cela signifie de rechercher dans le répertoire en cours de manière récursive les fichiers ne contenant pas ".php" dans le chemin et de les copier dans /destination/folder/.

Comme demandé, une ventilation plus spécifique des arguments:

  • . - Emplacement pour démarrer la recherche - dans ce cas, le répertoire actuel
  • ! - Opérateur "Non", inverser le résultat du test suivant
  • -iregex - Test d'expression régulière insensible à la casse. Le prochain argument est l'expression.
  • ".*\.php.*" - Correspondance d'expression régulière <Anything>.php<Anything> - Tout fichier contenant ".php" quelque part dans le chemin. (Remarque: y compris dans un dossier contenant le nom ".php", vous aurez besoin d'une expression plus complexe pour ne faire correspondre que les fichiers.)
  • -exec - Exécute une commande si les tests précédents renvoient true. L'argument suivant est la commande, tous les arguments restants jusqu'à ; sont passés à la commande. le {} est un argument spécial représentant le nom du fichier.
  • cp - La commande qui find` doit être exécutée sur chacun des noms de chemins correspondants.
  • {} - Le chemin d'accès au fichier trouvé, transmis à cp en tant qu'argument pour qu'il sache quel fichier copier
  • /destination/folder/ - argument passé à cp, indiquant à cp où il devrait copier le fichier.
  • \; - Ceci est le ; terminateur recherché par -exec. Nous y échappons avec un \ afin que votre shell n'essaie pas de l'analyser, mais l'alimente comme un argument de la commande (find)

Il est assez difficile d'écrire une expression régulière qui correspond à "chaînes qui n'ont pas .php", nous demandons donc à find de rechercher les chaînes qui do contiennent .php et inversons ensuite les résultats avec !.

26
Darth Android

Vous pouvez utiliser quelques autres outils de la console, tels que grep et xargs.

ls -1 some_folder | egrep 'some_extended_regex' | xargs cp -t destination_folder
9
0xAF