在BASH中获取相对路径

5

我已经搜索了一下,但是我猜没有太多人需要处理路径相关的内容。 所以我正在尝试编写一个bash脚本来使用tta和cue文件转换我的音乐收藏。 我的目录结构如下:/Volumes/External/Music/Just/Some/Dirs/Album.tta 用于tta文件和 /Volumes/External/Cuesheets/Just/Some/Dirs/Album.cue 用于cue表。

我的当前方法是将 /Volumes/External 设置为“root_dir”,并获取相对于 $ROOT_DIR/Music 的 album.tta 文件的路径(在这种情况下,这将是 Just/Some/Dirs/Album.tta),然后将此结果添加到 $ROOT_DIR/Cuesheets 中,并将后缀从 .tta 更改为 .cue。

我当前的问题是,dirname 返回的路径是它们本身,这意味着当我的当前文件夹是 $ROOT_DIR/Music 并且给出了绝对路径时,/Volumes/External/Music/Just/Some/Dirs 不会被转换为 ./Just/Some/Dirs/。

附://如果有人遇到类似的问题,这是脚本:

#!/bin/bash
ROOT_DIR=/Volumes/External
BASE="$1"

if [ ! -f "$BASE" ]
then
    echo "Not a file"
    exit 1
fi

if [ -n "$2" ]
then
    OUTPUT_DIR="$HOME/tmp"
else
    OUTPUT_DIR="$2"
fi
mkfdir -p "$OUTPUT_DIR" || exit 1

BASE=${BASE#"$ROOT_DIR/Music/"}
BASE=${BASE%.*}

TTA_FILE="$ROOT_DIR/Music/$BASE.tta"
CUE_FILE="$ROOT_DIR/Cuesheets/$BASE.cue"
shntool split -f "${CUE_FILE}" -o aiff -t "%n %t" -d "${OUTPUT_DIR}" "${TTA_FILE}"
exit 0

1
我不清楚这里的问题是什么。 - drysdam
问题是如何从绝对路径中获取特定的相对部分。在我的情况下,$BASE以及如何创建它是相关的部分。我之所以提及我的意图,是因为我不确定我的方法是否聪明,因为我相信总有更好的方法来做任何事情。 - MechMK1
2个回答

9
如果您的Cuesheets目录始终与您的音乐目录位于同一目录中,则可以从路径中删除root_dir,剩下的就是相对路径。如果您已经有了album_path的路径(album_path=/Volumes/External/Music/Just/Some/Dirs/Album.tta),并且设置了root_dir(root_dir=/Volumes/External),只需执行${album_path#$root_dir}即可。这将从album_path的开头修剪掉root_dir,因此您将得到album_path=Just/Some/Dirs/Album.tta
有关bash字符串操作的更多信息,请参见bash docs
编辑:// 将${$album_path#$root_dir}更改为${album_path#$root_dir}。

1
哦不,我完全忘记了 # 可以删除字符串。非常感谢你,你为我节省了一晚上的脚本编写和尴尬时刻,当我意识到解决方案是如此简单,并且我按照那种方式排序cue表的原因。 - MechMK1
应该是 ${album_path#$root_dir/} -- album_path 上没有 $,$root_dir 后面要加上 /,这样可以删除分隔符,避免被误认为是绝对路径。 - Gordon Davisson

1

好的,我之前用过几种方法来解决这个问题。我不建议修改路径和pwd环境变量,因为我曾经见过一些灾难性的事件。

以下是我的建议:

CURRENTDIR=/Volumes/External/Music # make sure you check the existence in your script
...
SEDVAL=$(echo $CURRENTDIR | sed s/'\/'/'\\\/'/g)
#run your loops for iterating through files
for a in $(find ./ -name \*ogg); do
  FILE=`echo $a | sed s/$SEDVAL/./g`  # strip the initial directory and replace it with .
  convert_file $FILE # whatever action to be performed
done

如果这是你经常要做的事情,我建议你写一个专门的脚本来处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接