Come puoi spostare (o copiare) tutti i file in una directory con lo stesso prefisso del nome file?


9

Usando Bash

Quindi diciamo che ho un sacco di file posizionati casualmente in una directory principale ~/src, voglio prendere tutti i file corrispondenti a un determinato suffisso e spostarli (o copiarli) in una ~/distdirectory.

Supponiamo a questo scopo che tutti i nomi di file abbiano questa convenzione di denominazione:

<filename_prefix>.<filename_suffix>

Ho scoperto che questo era un modo rapido per ottenere tutti i file con un particolare filename_suffixe metterli in una cartella dist:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Ora un ulteriore passo ... come posso usare l'output di find, in questo caso filename, e usare il filename_prefixper generare una directory con lo stesso nome ~/diste quindi spostare (o copiare) tutti i file con quel prefisso nella directory appropriata?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

In sostanza, come posso cambiare il comando sopra (o forse usare un altro comando), per creare una struttura come questa

(PRODUZIONE)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

da un albero di directory come questo?

(INGRESSO)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini

Risposte:


10

Sarebbe un inferno dire findcosa fare in questo caso.

Meglio usare la shell:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Usare shopt -s globstarper far funzionare il **glob (o usare zsh!). E rimuovi la echos in seguito se il comando stampa ciò che desideri.


usando bash è lo stesso?
qodeninja,

@codeninja shopt -s globstar, vedi la mia modifica. Se ci sono solo due livelli, è possibile utilizzare */*.*e lo snippet funzionerà in qualsiasi shell.
Gilles 'SO- smetti di essere malvagio' il

2

riga di comando cheating find:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

in realtà una soluzione per chiamare lo script bash in find LOL.

= P


1
Indovina cosa succede se c'è un file che si chiama ... happy rm -rf /! Questo tipo di codice merita un -1.
Stéphane Gimenez,

La tua modifica non è abbastanza: diciamo che hai cliccato su un link e scaricato Yay" rm -rf / "Rox0r.avi, di nuovo c'è un problema ...
Stéphane Gimenez

(E non c'è modo di rendere sicuro questo tipo di sostituzione).
Stéphane Gimenez,

1
Ah forse è possibile farlo diversamente. Sembra che le seguenti opere: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Beh, è ​​abbastanza inutile comunque.
Stéphane Gimenez,

1
@ StéphaneGimenez fatto, bash non è l'unica cosa da usare. LOL
yuyichao
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.