Ubuntu bash脚本:如何通过最后一个斜杠拆分路径?

I Z*_*I Z 46 bash split

我有一个文件(比如说list.txt),它包含文件的相对路径,每行一个路径,即这样的东西:

foo/bar/file1
foo/bar/baz/file2
goo/file3
Run Code Online (Sandbox Code Playgroud)

我需要编写一个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
Run Code Online (Sandbox Code Playgroud)

我怎么拆分?当路径没有斜线时,这会在退化的情况下工作吗?

谢谢

pio*_*kuc 102

使用basenamedirname,这就是你所需要的.

part1=`dirname "$p"`
part2=`basename "$p"`
Run Code Online (Sandbox Code Playgroud)

  • 当然,这样的破坏是微不足道的:`part1 ="$(dirname"$ p")"`和`part2 ="$(basename"$ p")"` (6认同)
  • 一旦文件名包含空格或有趣的符号,这将会惨遭打破...`: - (` (3认同)

gni*_*urf 14

适当的100%bash方式,对于有空格或有趣符号的文件名是安全的(提供inner_process.sh正确处理它们,但这是另一个故事):

while read -r p; do
    [[ "$p" == */* ]] || p="./$p"
    inner_process.sh "${p%/*}" "${p##*/}"
done < list.txt
Run Code Online (Sandbox Code Playgroud)

并且它不会为每个文件分叉dirnamebasename(在子shell中).

[[ "$p" == */* ]] || p="./$p"这里的行是为了以防万一$p,不包含任何斜杠,然后它会./在它之前.

有关和符号的详细信息,请参阅" Bash参考手册"中的" Shell参数扩展"部分.%##


Phi*_*uck 7

我从这个来源找到了一个很好的解决方案。

p=/foo/bar/file1
path=$( echo ${p%/*} )
file=$( echo ${p##*/} )
Run Code Online (Sandbox Code Playgroud)

这也适用于路径中的空格!

  • subshel​​l + echo 也是完全不必要的,并且当前的解决方案由于未加引号的扩展而遇到了常见的分词问题。不要写这个。只需使用 `path=${p%/*}` 和 `file=${p##*/}`。或者使用“basename”和“dirname”。 (7认同)
  • 而是 `${p##*/}` (3认同)