¿Cómo puedo forzar solo rutas relativas en la salida "buscar"?

25

Estoy tratando de crear un script que pueda comprimir archivos con una cierta extensión en varios directorios en una sola tar-ball. Actualmente lo que tengo en el archivo de script es:

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

¿Dónde $rootDirestá la ruta base para buscar?

Esto está bien, excepto que las rutas son absolutas en el archivo tar. Preferiría que los caminos sean relativos $rootDir. ¿Cómo haría para hacer esto?

Ejemplo de corriente tar -tf docs.tardonde $rootDirse /home/username/testemite:

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

Lo que deseo que sea la salida:

./subdir/test.doc
./second.doc
Shane
fuente

Respuestas:

12

Si ejecuta finddesde el directorio raíz deseado y no especifica un punto de partida absoluto en findlas opciones, generará rutas relativas a las tarinvocaciones de comandos que construye. Al igual que:

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

Si no desea cambiar el directorio de trabajo actual de forma permanente y está utilizando basho similar a su shell, puede hacerlo

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

en lugar.

Tenga en cuenta que pushd / popd no están presentes en todos los shells, así que verifique la página de manual según corresponda. Están presentes en bash, pero no en la implementación de base sh, por lo que, si se usa explícitamente /bin/bash, puede confiar en ellos, no puede hacerlo si un script lo solicita /bin/sh(ya que esto puede mapearse a un shell más pequeño que no tiene mejoras de bash)

David Spillett
fuente
Gracias. Trabajó brillantemente. No me di cuenta de que Linux tenía pushd / popd.
Shane
3
O simplemente use cd $rootDiry cd - (al menos en bash). ( cd $rootDir ; find ... )También sería posible, es decir, hacer todo en una subshell.
Daniel Beck
9

Puede usar el %Pformato en la -printfdirectiva:

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

se mostrará en su ejemplo:

subdir/test.doc
second.doc

Luego puede usar esta findlista en una forexpresión, para ejecutar nuestro comando exec, como en:

for f in $( find ${rootDir} -name '*.doc' -printf "%P\n" );
do
    tar rvf docs.tar ${f}
done
Gabriel
fuente
1
La solución aceptada funciona pero es básicamente un truco. En mi humilde opinión, esta debería ser la solución correcta a la pregunta.
Narcolessico
Gracias narcolessico. También es MHO :-)
Gabriel