2011-06-18 19 views
5

Qual è l'equivalente di bash a os.path.normpath? Nello specifico sono interessato a rimuovere il numero iniziale ./ dato durante l'esecuzione di find.equivalente in bash di os.path.normpath di Python?

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

Per curiosità, perché? './foo' funziona bene, quindi i programmi non dovrebbero importare ... – Nemo

+0

'./Makefile' non è un percorso assoluto, quindi puoi usarlo senza problemi. Là. Problema risolto. – tzot

+0

@Nemo: i percorsi normalizzati sono utilizzati in un file manifest. Altrimenti non sarebbe un problema. –

risposta

2

Bene, per questo, si può semplicemente pipe l'output attraverso sed, non c'è bisogno di normalizzare l'intero percorso:

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

che sbarazzarsi di tutti ./ sequenze all'inizio di una linea.

La seguente trascrizione mostra in azione:

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 

Come potete vedere, ho uno standard di denominazione abbastanza intuitivo per i miei script di shell temporanei :-)

0

Eventuali duplicati here. Ma se siete solo interessati a striping off leader ./ si può solo fare

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

Penso che questo sia in realtà sbagliato. Devi sfuggire a '.'. –

+0

@Matt, divertente, mi era sfuggito. Ma ho scelto un po 'di formattazione> che non l'ha mostrato correttamente. Scelgo la pre-formattazione ora e mostra –

1

solito faccio questo utilizzando find s' -printf argomento.

Il seguente funziona bene se siete alla ricerca di percorsi multipli:

find path1 path2 

Il seguente funziona bene se siete alla ricerca in .:

find -printf '%P\n' 

Se si dispone di percorsi misti (es. find path1 path2 .), dovresti usare sed.

+0

Non sono sicuro di cosa intendi per percorsi misti che sembra funzionare senza. –

2

Sto faticando a trovare un caso in cui vorrei utilizzare os.path.normpath. In un sistema che ha collegamenti simbolici, come Unix o Windows, il valore che restituisce non possono designare lo stesso file:

$ 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/.. è /tmp/one, non /tmp!

Su Linux, readlink -- "$filename" normalizza tutti i collegamenti simbolici in un percorso. Il nome del file restituito designa lo stesso file di $filename al momento dell'esecuzione del comando (potrebbe non, in seguito, se uno dei collegamenti simbolici coinvolti viene modificato). Ma la maggior parte delle volte non è necessario: basta mantenere $filename così com'è.

Se si desidera rimuovere un prefisso ./ per motivi estetici, è sufficiente separarlo in modo specifico.

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

I percorsi normalizzati sono utilizzati in un file manifest. Non possono essere assoluti. –

1

ne dite:

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

?

Non credo ci sia alcuna funzione bash incorporata per fare tutto ciò che fa Python normpath. Potrebbe essere meglio descrivere esattamente quale trasformazione si desidera eseguire.

+0

La stampa di Pity commuta il comportamento tra 2 e 3 :) –

1

scrivere qualcosa del genere:

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

Puoi aggiungere qualche spiegazione per il tuo codice? – Ren

+1

Ho aggiunto alcuni commenti. Per rendere il percorso non assoluto "pulizia" dovremmo cambiare la condizione del ciclo e aggiungere l'handle alla situazione quando il percorso supera il suo punto di partenza (aggiungi gli elementi necessari "../") –

0

ho trovato: si chiama realpath! Tipo qualcosa come:

realpath .. # the most interesting thing 

o

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

e godere!

+0

Sarebbe stato bello, ma non è standard. – GreenAsJade