Come spostare tutti i file all'interno delle sottocartelle presenti qui


8

Ho anche 50 cartelle con alcune sottocartelle, con un totale di oltre 1000 file audio. Devo rimuovere tutte le sottocartelle e mettere tutti i file al livello attuale. Ho provato mv */* ./ma si lamenta: elenco argomenti troppo lungo

Risposte:


7

Presumo che l'estensione dei tuoi file audio sia .mp3

find <AudioFolderPath> -name '*.mp3' -exec mv -it <YourTargetFolder> {} +

Appunti:

  • Sostituisci .mp3con l'estensione dei tuoi file audio

  • Sostituisci <AudioParentFolderPath>con la cartella principale che contenga le tue sottocartelle.

  • Sostituisci <YourTargetFolder>con il percorso della cartella in cui devi inserire tutti i file.

  • Se i file di rimorchio da sottocartelle diverse hanno lo stesso nome, ne verrà spostato solo uno.

modifica: Come ha detto Costas : "L' -iinterruttore rende mvinterattivo, verrà richiesto prima di sovrascrivere i file esistenti"


'-t' ti consente di specificare prima la destinazione? (dato che non ho questa opzione sul mio "mv" qui, posso solo supporre che quando metti prima la cartella di destinazione e poi l'elenco dei file da spostare lì ... ma in caso contrario, questo cercherà di adattarsi a tutti nell'ultimo nome file, dando un avviso) tpotrebbe essere per "target"?
Olivier Dulac,

Sì, come hai detto, -tconsenti di specificare prima la destinazione. dalla mvpagina del manuale: -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY
Muhammad,

1
si prega di notare che questa è l'opzione GNU mv e non è disponibile su tutti i computer (almeno in alcuni ambienti di produzione). Fornisco una soluzione più portatile, ma la tua funziona bene per Linux
Olivier Dulac il

si @OlivierDulac, hai ragione, grazie per la tua nota.
Muhammad,

4
find . -type f -mindepth 2 -exec mv -t ./ {} +

Si noti che quel comando sovrascriverà tutti i file con lo stesso nome. È possibile utilizzare questo per essere richiesto prima di sovrascrivere:

find . -type f -mindepth 2 -exec mv -it ./ {} +

Spiegazione

  • -type f : trova solo file regolari.
  • -mindepth 2 : trova solo i file nelle sottodirectory.
  • -exec mv -it ./ {}: -execsignifica "esegui questo comando su ogni file trovato". Il {}sarà sostituito con i nomi dei file. Lo -iswitch rende mvinterattivo, verrà richiesto prima di sovrascrivere i file esistenti e -timposta la directory di destinazione su ./.
  • +: mette insieme i file (in una riga dell'argomento) quanti sono gli shell che possono operare con il comando per invocare i tempi minimi di comando (non uno per uno ma uno a più).

Per quanto riguarda le ulteriori eliminazioni di cartelle vuote puoi usare lo stesso recepie:

find . -type d -empty -delete

1
-type fseleziona solo file semplici, esclusi collegamenti simbolici, pipe denominate e simili. Per spostare tutti i file diversi dalle directory che puoi fare ! -type d.
Jimmij,

@jimmij Suppongo che nessuno memorizzi i file audio come named pipe o qualcos'altro. Se ti preoccupi dei link simbolici puoi utilizzare il -Lparametro
Costas

1
-iè standard, -tè solo GNU (niente a che fare con Linux, che è solo un kernel trovato in alcuni sistemi GNU e non GNU)
Stéphane Chazelas,

Concordo con @ StéphaneChazelas: -tnon esiste su alcuni sistemi (come un AIX non così antico)
Olivier Dulac,

@OlivierDulac È quasi impossibile trovare una decisione per soddisfare tutti, quindi le diverse varianti sono benvenute. Nessuno ti proibisce di cambiare stringa infind . -type f -mindepth 2 -exec mv {} ./ \;
Costas,

2

Sì, questo è un limite alla dimensione cumulativa degli argomenti e dell'ambiente passati alla execve()chiamata di sistema quando si esegue un comando esterno.

Con zsh, puoi invece usare il suo builtin mv:

zmodload -F zsh/files +b:zf_mv
zf_mv ./*/* .

Oppure usa zargsper spezzare l'elenco in blocchi gestibili:

autoload zargs
zargs -Ifiles ./*/* -- mv files .

Con ksh93:

command -x mv ./*/* .

Con GNU xargse GNU mvcon una shell in cui printfè incorporato (la maggior parte, mkshessendo la notevole eccezione):

printf '%s\0' ./*/* | xargs -r0 mv -t .

Si prega di tenere presente che OP desidera spostare solo i file, non le directory, quindi è necessario occuparsene. Nel zshcaso in cui puoi mettere alcuni qualificatori glob , ad esempio (.)o (^/)dopo l'ultimo *.
Jimmij,

0

Una soluzione abbastanza portatile potrebbe essere:

trova tutti i file in ogni sottocartella e spostali nella directory corrente

find ./*/ -type f -print | xargs mv -i "{}" ./

Puoi aggiungere una via | egrep "\.au$|\.mp3$|\.ac3$"di mezzo per assicurarti che i file che hai trovato siano file con estensione audio (aggiungi tutte le estensioni necessarie per coprire tutti i tipi, ne fornisco solo 3 comuni)


Nel tuo caso non è necessario chiamare findaffatto. Quanto basta echooprintf
Costas,

@Costas: la menzione di OP ci sono così tanti file che "*" non può essere espanso ... Qui ho solo espandere i nomi delle 50 cartelle, e il resto è gestito da xargs
Olivier Dulac il

Ma findnon risolvere il problema ma xargsfarlo.
Costas,
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.