2012-12-07 11 views
28

私はこのような何か、ファイルへの相対パスを含むファイル(list.txtと呼ばれると言う)を持って、1行に1つのパス、すなわち:私は、一度に1つのパスを処理bashスクリプトを記述する必要がUbuntuのbashスクリプト:最後のスラッシュでパスを分割する方法は?

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

を、それを最後のスラッシュで分割し、2つのパスを引数として別のプロセスに渡します。これまでのところ、私はループ部分のみを持っています:

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 

どのように分割しますか?パスがスラッシュを持たない縮退したケースではこれは機能しますか?

Thxを

答えて

65

使用basenamedirname、それはあなたが必要とするすべてです。スペースや面白い記号を持つファイル名について安全である

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

これは最後のスラッシュが必要なので、実際には "part1 =' dirname $ p'/"ですが、それ以外は完璧です:-) –

+3

ファイル名にスペースや面白い記号が含まれるとすぐに破損します。 ':-(' –

+1

そのような破損は共同で解決するのは簡単ではありません$ 1( "dirname" $ p ")"と 'part2 =" $(ベース名 "$ p") " – zenaan

11

適切な100%のbashの方法とは(inner_process.shがそれらを正しく処理して、それはまた別の話です):

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

、それはしていませんファイルごとにdirnamebasename(サブシェル内)。

$pにスラッシュが含まれていない場合は、./の先頭に追加されます。

%##記号詳細はBash Reference ManualShell Parameter Expansionセクションを参照してください。

-3

xmlのファイル拡張子を検索して置き換える例を次に示します。

for files in $(ls); do 

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

lsを解析しないでください。 [理由を知るにはこちらをご覧ください](http://mywiki.wooledge.org/ParsingLs) – XZS

2

(ほど効率的でない場合)短くてシンプルに保ちながら、@のpiokucの答えの@のgniourf_gniourfの批判に対応するために:

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

(私はコメントに反応しているだろうが、それは構文的に不可能です。 )

関連する問題