Domanda

Prova di rinominare una serie di file su un server Linux. Trovare i file che voglio è facile:

find . -type f -wholename \*.mbox

Naturalmente, essendo file mbox, alcuni di essi hanno spazi nei nomi, quindi diventa:

find . -type f -wholename \*.mbox -print0

Sto eseguendo il piping su xargs in modo da poter rinominare i file:

find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}

L'eco dovrebbe restituire qualcosa come INBOX, dato INBOX.mbox, tuttavia, bash si lamenta:

bash: ${"{}"/.mbox/}: bad substitution

Come posso risolvere questo problema? Vorrei provare a tenerlo in una soluzione find / xargs, se possibile, in modo da non aggiungere molti costrutti loop attorno ad esso.

È stato utile?

Soluzione

Prova

find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh

Questo non è al 100% a prova di errore se alcuni file contengono caratteri di virgolette doppie, ma suppongo che tu possa ignorarlo :)

Altri suggerimenti

GNU Parallel http://www.gnu.org/software/parallel/ ha {.} che rimuove l'estensione:

find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}

Se sai che i nomi dei file non contengono \ n, anche questo funzionerà:

find . -type f -wholename \*.mbox | parallel mv {} {.}

Penso che tu abbia bisogno di questo:

find . -wholename \*.mbox | awk '{new=<*>; gsub("\.mbox<*>quot;, "", new) ; system("mv \"" <*> "\" \"" new "\"") }'

(dovrebbe essere compatibile sia con gawk che con mawk, testato su mawk). Non utilizza xargs, ma nota che non esegue il fork di un nuovo processo per ogni file spostato. Se devi spostare una grande quantità di file, noterai il vantaggio. Attenzione: se uno qualsiasi dei file conterrà una nuova riga nel suo nome, avrai dei problemi (ma se questo è un problema, Dio sia con te).

Migliorate ulteriormente questa soluzione utilizzando xargs per eliminare più file in un'unica chiamata rm .

Se hai davvero bisogno di velocità, suggerirei di usare uno script Python invece di awk. Ciò farà tutti i rm senza un singolo fork.

Potresti usare rename (1)? Viene fornito con perl.

Puoi provare:

find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'

Il tuo problema è provare a reindirizzare xargs. A quel punto " {} " non significa nulla.

Per rinominare i file (Supponendo che tu sia sotto bash)

find . -type f -wholename \*.mbox -print0 | \
    while read I ; do
        mv $I $(echo $I | sed 's/\.mbox//') ;
    done ;

Ecco qua, questo dovrebbe fare il trucco ....

# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst

#

for file in `find . -type f`
do
mv $file ${file%.tst}.new
done

# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top