2011-06-18 13 views
5

¿Cuál es el equivalente equivalente a os.path.normpath? Específicamente, estoy interesado en eliminar el ./ principal dado al ejecutar find.equivalente bash de os.path.normpath de Python?

[email protected]:~/src/libtelnet-0.20/test$ find 
. 
./Makefile 
./Makefile.in 
./Makefile.am 
...
+4

Por curiosidad, ¿por qué? './foo' funciona bien, por lo que a los programas no les debe importar ... – Nemo

+0

'./Makefile' no es un nombre de ruta absoluto, por lo que puede usarlo sin problemas. Ahí. Problema resuelto. – tzot

+0

@Nemo: las rutas normalizadas se usan en un archivo de manifiesto. De lo contrario, no sería un problema en absoluto. –

Respuesta

2

Bueno, para eso, simplemente puede canalizar la salida a través sed, usted no tiene que normalizar toda la ruta:

your_command_goes_here | sed 's?^\./??' 

que logrará erradicar de todas las secuencias ./ al inicio de una linea

La siguiente transcripción muestra esto en acción:

pax$ find -name 'qq*sh' 
./qq.ksh 
./qq.sh 
./qq.zsh 
./qq2.sh 
./qq2.zsh 
./qqq/qq.sh 

pax$ find -name 'qq*sh' | sed 's?^./??' 
qq.ksh 
qq.sh 
qq.zsh 
qq2.sh 
qq2.zsh 
qqq/qq.sh 

Como se puede ver, tengo un estándar de nomenclatura bastante intuitivo para mis scripts de shell temporales :-)

0

posible duplicado here. Pero si son sólo interesado en la creación de bandas que nos conduce ./ usted podría hacer

find -type f | sed 's/^\.\///' 
+0

Creo que esto es realmente incorrecto. Debes escapar del '.' –

+0

@Matt, gracioso, me había escapado. Pero elegí algún formato> que no lo mostró correctamente. Elijo pre formatear ahora y muestra –

1

que suelo hacer esto mediante el uso find 's -printf argumento.

La siguiente funciona bien si usted está buscando en varias rutas:

find path1 path2 

La siguiente funciona bien si usted está buscando en .:

find -printf '%P\n' 

Si usted tiene unos trayectos mixtos (ej. find path1 path2 .), tendrías que usar sed.

+0

No estoy seguro de lo que quiere decir con rutas mixtas que parece funcionar sin él. –

2

Estoy luchando por encontrar un caso en el que me gustaría usar os.path.normpath. En un sistema que tiene enlaces simbólicos, tales como Unix o Windows, el valor que devuelve no puede designar el mismo archivo:

$ mkdir /tmp/one /tmp/one/two 
$ ln -s /tmp/one/two /tmp/foo 
$ python -c 'import os.path; print os.path.normpath("/tmp/foo/..")' 
/tmp 
$ ls /tmp/foo/.. 
two 

/tmp/foo/.. es /tmp/one, no /tmp!

En Linux, readlink -- "$filename" normaliza todos los enlaces simbólicos en una ruta. El nombre del archivo que devuelve designa el mismo archivo que $filename en el momento en que se ejecuta el comando (puede que no, más adelante, si se cambia uno de los enlaces simbólicos involucrados). Pero la mayoría de las veces, eso no es necesario: simplemente mantenga $filename tal como está.

Si desea eliminar un prefijo ./ por razones estéticas, simplemente quítelo específicamente.

filename=${filename#./} 
find | sed -e 's!^\./!!' 
+0

Las rutas normalizadas se usan en un archivo de manifiesto. No pueden ser absolutos –

1

¿Qué tal:

newpath=`echo -n "$oldpath" | python -c 'import sys, os; print os.path.normpath(sys.stdin.readline())'` 

?

No creo que haya ninguna función de bash incorporada para hacer todo lo que hace el normpath de Python. Es mejor que describa exactamente qué transformación desea realizar.

+0

Comportamiento de interruptores de impresión compasiva entre 2 y 3 :) –

1

escribir algo como esto:

normpath() { 
    [[ -z "$1" ]] && return 

    local skip=0 p o c 

    p="$1" 
    # check if we have absolute path and if not make it absolute 
    [[ "${p:0:1}" != "/" ]] && p="$PWD/$p" 

    o="" 
    # loop on processing all path elements 
    while [[ "$p" != "/" ]]; do 
     # retrive current path element 
     c="$(basename "$p")" 
     # shink our path on one(current) element 
     p="$(dirname "$p")" 

     # basename/dirname correct handle multimple "/" chars 
     # so we can not warry about them 

     # skip elements "/./" 
     [[ "$c" == "." ]] && continue 
     if [[ "$c" == ".." ]]; then 
      # if we have point on parent dir, we must skip next element 
      # in other words "a/abc/../c" must become "a/c" 
      let "skip += 1" 
     elif [[ 0 -lt $skip ]]; then 
      # skip current element and decrease skip counter 
      let "skip -= 1" 
     else 
      # this is normal element and we must add it to result 
      [[ -n "$o" ]] && o="/$o" 
      o="$c$o" 
     fi 
    done 

    # last thing - restore original absolute path sign 
    echo "/$o" 
} 
+0

¿Puede agregar alguna explicación para su código? – Ren

+1

He agregado algunos comentarios. Para hacer una "limpieza" no absoluta del camino, deberíamos cambiar la condición del bucle y agregar el manejador a la situación cuando la ruta vaya por encima de su punto de inicio (agregar el conteo requerido "../" elementos) –

0

lo encontré: se llama realpath! Tipo algo como:

realpath .. # the most interesting thing 

o

realpath . # equivalent to `pwd' and to `echo $PWD' 

y disfrutar!

+0

Hubiera estado bien, pero no es estándar. – GreenAsJade

Cuestiones relacionadas