ファイルがあります(たとえばlist.txt
)ファイルへの相対パス、1行に1つのパス、つまり次のようなものが含まれます。
foo/bar/file1
foo/bar/baz/file2
goo/file3
一度に1つのパスを処理し、最後のスラッシュで分割してから、2つのパスを引数として渡す別のプロセスを起動するbashスクリプトを作成する必要があります。これまでのところ、ループ部分のみがあります。
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
必要なのはbasename
とdirname
だけです。
part1=`dirname "$p"`
part2=`basename "$p"`
適切な100%bashの方法で、スペースまたは面白い記号を含むファイル名に関しては安全です(inner_process.sh
がそれらを正しく処理しますが、それは別の話です):
while read -r p; do
[[ "$p" == */* ]] || p="./$p"
inner_process.sh "${p%/*}" "${p##*/}"
done < list.txt
また、ファイルごとにdirname
およびbasename
(サブシェル内)をフォークしません。
行[[ "$p" == */* ]] || p="./$p"
は、$p
にスラッシュが含まれていない場合に備えて、./
を先頭に追加しています。
%
の詳細については、 Bash Reference Manual の Shellパラメーター展開 セクションを参照してください。 ##
シンボル。
@piokucの回答に対する@gniourf_gniourfの批判に対応し、簡潔かつシンプルに(効率的でないとしても)維持するには:
part1=`dirname "$p"`
part2=`basename "$p"`
(私はコメントで答えたでしょうが、それは構文的に不可能です。)
これからの素晴らしい解決策 source
p=/foo/bar/file1
path=$( echo ${p%/*} )
file=$( echo ${p##/*/} )
これは、パス内のスペースでも機能します!