Come posso forzare solo i percorsi relativi nell'output "trova"?


25

Sto tentando di creare uno script in grado di comprimere i file con una determinata estensione in una serie di directory in una singola tar-ball. Attualmente quello che ho nel file di script è:

find "$rootDir" -name '*doc' -exec tar rvf docs.tar {} \;

Dov'è $rootDiril percorso base da cercare.

Questo va bene tranne che i percorsi sono assoluti nel file tar. Preferirei che i percorsi fossero relativi $rootDir. Come potrei fare per fare questo?

Esempio di corrente tar -tf docs.tardove $rootDirviene /home/username/testemesso:

home/username/test/subdir/test.doc
home/username/test/second.doc

Cosa desidero che sia l'output:

./subdir/test.doc
./second.doc

Risposte:


12

Se esegui finddalla directory radice desiderata e non specifichi un punto di partenza assoluto nelle findopzioni di, genererà percorsi relativi alle tarinvocazioni di comando che costruisce. Così:

cd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;

Se non si desidera modificare la directory di lavoro corrente in modo permanente e si utilizza basho simile alla propria shell, è possibile farlo

pushd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;
popd

anziché.

Nota che pushd / popd non sono presenti in tutte le shell, quindi controlla la pagina man come appropriato. Sono presenti in bash ma non nell'implementazione di base sh, quindi mentre usando esplicitamente /bin/bashpuoi fare affidamento su di essi non puoi se invece uno script lo richiede /bin/sh(poiché questo può essere mappato su una shell più piccola che non ha i miglioramenti di bash)


Grazie. Ha funzionato brillantemente. Non avevo capito che Linux aveva pushd / popd.
Shane,

3
O semplicemente usa cd $rootDire cd - (almeno in bash). ( cd $rootDir ; find ... )sarebbe anche possibile, cioè fare tutto in una subshell.
Daniel Beck

9

È possibile utilizzare il %Pformato nella -printfdirettiva:

find ${rootDir} -name '*.doc' -printf "%P\n"

mostrerà nel tuo esempio:

subdir/test.doc
second.doc

È quindi possibile utilizzare questo findelenco in forun'espressione, al fine di eseguire il nostro comando exec, come in:

for f in $( find ${rootDir} -name '*.doc' -printf "%P\n" );
do
    tar rvf docs.tar ${f}
done

1
La soluzione accettata funziona ma è sostanzialmente un trucco. IMHO questa dovrebbe essere la soluzione giusta alla domanda.
Narcolessico,

Grazie Narcolessico. È anche MHO :-)
Gabriel,
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.