2012-12-07 5 views
28

Ho un file (ad esempio chiamato list.txt) che contiene percorsi relativi ai file, un percorso per linea, vale a dire qualcosa di simile:Script bash di Ubuntu: come dividere il percorso per l'ultima barra?

foo/bar/file1 
foo/bar/baz/file2 
goo/file3 

ho bisogno di scrivere uno script bash che elabora un percorso alla volta, lo divide nell'ultima barra e quindi avvia un altro processo alimentando i due pezzi del percorso come argomenti. Finora ho solo la parte loop:

for p in `cat list.txt` 
do 
    # split $p like "foo/bar/file1" into "foo/bar/" as part1 and "file1" as part2 
    inner_process.sh $part1 $part2 
done 

Come dividere? Funzionerà nel caso degenere quando il percorso non ha barre?

Thx

risposta

65

Usa basename e dirname, questo è tutto ciò che serve.

part1=`dirname "$p"` 
part2=`basename "$p"` 
+0

Questo è in realtà "part1 =' dirname $ p'/"poiché ho bisogno dell'ultima barra, ma a parte questo è perfetto :-) –

+3

Questo si romperà miseramente non appena un nome file contiene uno spazio o simboli divertenti .. . ':-(' –

+1

Tale rottura è banale da risolvere di co urse: 'part1 =" $ (dirname "$ p") "' e 'part2 =" $ (basename "$ p") "' – zenaan

11

Un modo corretto bash al 100% e che è sicuro per quanto riguarda i nomi dei file che hanno spazi o simboli divertenti (fornito inner_process.sh li gestisce in modo corretto, ma questa è un'altra storia):

while read -r p; do 
    [[ "$p" == */* ]] || p="./$p" 
    inner_process.sh "${p%/*}" "${p##*/}" 
done < list.txt 

e non lo fa fork dirname e basename (in subshell) per ogni file.

La riga [[ "$p" == */* ]] || p="./$p" è qui nel caso in cui $p non contenga alcuna barra, quindi antepone ./.

Vedere la sezione Shell Parameter Expansion nella Bash Reference Manual per maggiori informazioni sui % e ## simboli.

-3

Ecco un esempio per trovare e sostituire le estensioni di file in xml.

for files in $(ls); do 

    filelist=$(echo $files |cut -f 1 -d "."); 
    mv $files $filelist.xml; 
done 
+4

Non analizzare mai ls. [Vedi qui per sapere perché.] (Http://mywiki.wooledge.org/ParsingLs) – XZS

2

Per rispondere a @ di gniourf_gniourf critica della risposta di @ piokuc mantenendolo breve e semplice (se non il più efficiente):

part1=`dirname "$p"` 
part2=`basename "$p"` 

(avrei risposto in un commento, ma questo è sintatticamente impossibile.)

Problemi correlati