从Unix树中删除路径前缀

6

我有一个UNIX命令要求,其中路径类似于:

path/to/file/manyfiles.extensions

现在我希望输出的结果类似于-

file/manyfiles.extensions

现在我可以列出 /path/to 和 /path,然后逐个删除它们。

但是有时候我只会得到 "/path/to" 作为输入,而我需要一条命令从树中同时删除这两个路径。

你可能会认为我可以列出要删除的两个文件夹,但是在许多情况下,我会得到包含12-13个子文件夹的结构,在很多情况下我只需要第一个和最后一个文件夹。

例如 - `源文件 - 目标/classes/

删除前缀 - 目标`

结果:

classes/my/code/HelloWorld.class
classes/my/code/HelloWorldImpl.class
classes/my/code/Main.class

1
你的问题不是很清楚。你能否再尝试用一些例子来清晰地解释一下? - anubhava
让我更简单地解释一下 - 假设你有一个像这样的地址 - folder2/folder3/folder4/folder5/folder6/folder7/file.txt 现在这个结构处理起来太耗时间了 我希望将结构缩减为类似于这样的形式 folder6/folder7/file.txt - Rahul
所以你想要最后2个子文件夹和文件名在结尾? - anubhava
下面发布了一个答案。 - anubhava
3个回答

17

如果我理解您的问题正确,您想要从一个路径中删除给定的前缀。假设有一个声明 path=/a/path/to/a/directory 和一个模式 *a/,在Bash中有两种方法可以去除与该模式匹配的前缀:

echo ${path#*a/}    # outputs "path/to/a/directory"
echo ${path##*a/}   # outputs "directory"

第一个变体是非贪婪的,并在第一次匹配时停止,而第二个变体是贪婪的,并在模式的最长可能匹配处停止。这里的路径中出现了两次模式*a/,因此结果是不同的。

在您的情况下,模式将类似于path/to,路径将是path/to/file/manyfiles.extensions,因此以下之一将起作用,具体取决于您是否需要贪婪:

path=path/to/file/manyfiles.extensions
path=${path#*path/to/}   # assigns "file/manyfiles.extensions" to $path
或者
path=path/to/file/manyfiles.extensions
path=${path##*path/to/}  # assigns "file/manyfiles.extensions" to $path

如需参考,请阅读关于 Bash参数扩展 的内容。


2
你需要使用basename命令来剥离文件名中的目录,再结合dirname命令可以得到仅包含目录结构的信息。
然后,你可以使用所需的逻辑来获取需要保留的目录部分,并将其与文件名重新组合。
类似于以下伪代码:
original_file='/some/long/path/to/a/file'
file_name=$(basename $original_file)
dir_name=$(dirname $original_file)

short_dir='...use regex or whatever logic you need to pear ${dir_name} down (we'll need more info to help with this)'

new_file="${short_dir}/${file_name}"

1
你可以尝试使用 grep -oP:
p="older2/folder3/folder4/folder5/folder6/folder7/file.txt"
s=$(grep -oP '([^/]+/){2}[^/]+/?$' <<< "$p")
echo "$s"

OUTPUT:

folder6/folder7/file.txt

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