Come si usano le espressioni regolari con il comando cp in Linux?


22

Sto tentando di copiare solo un sottoinsieme di file da una directory all'altra utilizzando cpma sono accolto con il messaggio cp: cannot stat [^\.php]': No such file or directory. C'è un modo per usare le espressioni regolari usando solo il cpcomando?

Risposte:


29

No.

Il cpcomando non possiede la capacità di elaborare nessuno dei suoi argomenti come espressioni regolari. Persino i caratteri jolly non sono gestiti da esso (o dalla maggior parte degli eseguibili); piuttosto sono gestiti dalla shell.

cp test/* test2/è in realtà espanso da bash, e tutto ciò cpche vede veramente per i suoi argomenti sono cp test/file1 test/file2 test/file3 test2/(o qualunque cosa sia appropriata in base al contenuto reale di test/).

Inoltre, non credo che la tua espressione [^\.php]corrisponda a ciò che desideri (non corrisponde solo ai file che contengono .php).

Probabilmente vuoi esaminare l' findutilità per filtrare un elenco di file in base all'espressione regolare, quindi utilizzare xargsper applicare l'elenco di file restituito al cpcomando (supponendo che find non abbia un gestore integrato per la copia dei file; I ' non ho familiarità con lo strumento).

Potresti provare:

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

Questo dice di cercare ricorsivamente nella directory corrente i file che non contengono ".php" nel percorso e copiarli /destination/folder/.

Come richiesto, una ripartizione più specifica degli argomenti:

  • . - Posizione per iniziare la ricerca - in questo caso, la directory corrente
  • ! - Operatore "Non", invertire il risultato del test successivo
  • -iregex- Test di espressione regolare senza distinzione tra maiuscole e minuscole. L'argomento successivo è l'espressione.
  • ".*\.php.*"- Corrispondenza delle espressioni regolari <Anything>.php<Anything>- Qualsiasi file con ".php" da qualche parte nel percorso. (Nota, incluso l'essere all'interno di una cartella che contiene ".php" nel nome, avresti bisogno di un'espressione più complessa per abbinare solo i file)
  • -exec- Eseguire un comando se i test precedenti restituiscono true. L'argomento successivo è il comando, tutti gli argomenti rimanenti fino a ;vengono passati al comando. il {}è un argomento speciale che rappresenta il nome del file.
  • cp - Il comando che trova` dovrebbe essere eseguito su ciascuno dei nomi di percorso corrispondenti.
  • {}- Il percorso del file trovato, passato cpcome argomento in modo che sappia quale file copiare
  • /destination/folder/- argomento passato a cp, che indica cpdove dovrebbe copiare il file.
  • \;- Questo è il ;terminatore che -execsta cercando. Lo sfuggiamo con un \modo che la tua shell non tenti di analizzarlo e invece lo alimenta come argomento per il comando ( find)

E 'piuttosto difficile scrivere un'espressione regolare che corrisponde a "stringhe che non hanno .php", così abbiamo invece diciamo findper cercare stringhe che non contengono .phpe poi invertito i risultati con !.


2
find . -name [^\.php] -exec cp {} /path/to/location \;fare attenzione ai file con caratteri speciali.
Rob,

@Darth Android - Grazie. Non sapevo che cpe altri binari non fossero in grado di espandere le espressioni regolari. Ti dispiacerebbe elaborare cosa significano ciascuna delle opzioni e degli argomenti nell'esempio di esempio che hai dato? So che .si riferisce alla directory corrente, ma che cosa !, {}, \;, ecc riferisco a come bene che cosa significano? Ad esempio, perché devi scappare ;?
PeanutsMonkey,

@Rob - Cosa intendi con file speciali?
PeanutsMonkey,

@Rob - Ho tentato un'espressione simile per rimuovere file specifici, ma alla fine ha eliminato tutti i file nella directory. Il mio comando era find . -name '[^\.txt]' -exec rm {} \;quindi la mia riluttanza a usare find. Probabilmente un errore da parte mia, ma non sono sicuro di cosa ho fatto di sbagliato. Per quanto riguarda la mia comprensione si {}riferisce a ogni file trovato dal comandofind . -name '[^\.txt]'
PeanutsMonkey il

Cosa stai cercando di abbinare alla regex?
Rob,

10

Puoi usare pochi altri strumenti dalla console, come grep e xargs.

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

In che cosa {}differisce da quello di -t?
PeanutsMonkey,

2
Non molto in questo caso. La sintassi alternativa per xargs sarebbe 'xargs cp {} destination_folder'. la sintassi cp standard accetta una o più origini e una destinazione alla fine, quando si utilizza l'opzione -t, è possibile specificare la destinazione dopo -t, quindi utilizzare il resto della riga per le fonti. Trovo solo l'opzione -t più conveniente in questo caso. Nell'altro esempio {} viene sostituito da ciò che viene reindirizzato a xargs (stdin), in questo caso il nome file.
0xAF,

-1

È possibile eseguire il comando seguente facile da usare:

find /home/usr/search_dir -iname *file_name_portion*.txt | xargs cp -t /home/usr/destination_folder

fantastico ah !!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.