Unix删除部分path

我试图删除string中的部分path。 我有path:

/path/to/file/drive/file/path/ 

我想删除第一部分/path/to/file/drive并产生输出:

 file/path/ 

注意:我在while循环中有几条path,在它们中都有相同的/path/to/file/drive ,但我只是想find如何去除所需的string。

我find了一些例子,但我无法让他们工作:

 echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:\2:' echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:2' 

\2作为string的第二部分,我显然做错了什么…也许有一个更简单的方法?

你也可以使用POSIX shell变量扩展来做到这一点。

 path=/path/to/file/drive/file/path/ echo ${path#/path/to/file/drive/} 

当变量被展开时, #..部分剥离了一个主要的匹配字符串; 如果你的字符串已经在shell变量中,比如你正在使用for循环,这个特别有用。 你可以使用%...从变量的末尾去掉匹配的字符串(例如一个扩展名)。 见bash手册页的血淋淋的细节。

如果你想删除一定数量的路径组件,你应该使用-d'/' cut 。 例如,如果path=/home/dude/some/deepish/dir

要删除前两个组件:

 # (Add 2 to the number of components to remove to get the value to pass to -f) $ echo $path | cut -d'/' -f4- some/deepish/dir 

保留前两个组件:

 $ echo $path | cut -d'/' -f-3 /home/dude 

删除最后两个组件( rev反转字符串):

 $ echo $path | rev | cut -d'/' -f4- | rev /home/dude/some 

要保留最后三个组件:

 $ echo $path | rev | cut -d'/' -f-3 | rev some/deepish/dir 

或者,如果你想删除特定组件之前的所有内容, sed将会工作:

 $ echo $path | sed 's/.*\(some\)/\1/g' some/deepish/dir 

或者在特定组件之后:

 $ echo $path | sed 's/\(dude\).*/\1/g' /home/dude 

如果你不想保留你指定的组件,这更容易:

 $ echo $path | sed 's/some.*//g' /home/dude/ 

如果你想保持一致,你可以匹配最后的斜线:

 $ echo $path | sed 's/\/some.*//g' /home/dude 

当然,如果你匹配几个斜线,你应该切换sed分隔符:

 $ echo $path | sed 's!/some.*!!g' /home/dude 

请注意,这些示例都使用绝对路径,您将不得不四处使用它们来处理相对路径。

如果你不想硬编码你要删除的部分:

 $ s='/path/to/file/drive/file/path/' $ echo ${s#$(dirname "$(dirname "$s")")/} file/path/ 

一个方法与sed做到这一点是

 echo /path/to/file/drive/file/path/ | sed 's:^/path/to/file/drive/::' 

使用邪恶奥托建议的${path#/path/to/file/drive/}肯定是这样做的典型/最好的方式,但是因为有很多sed的建议,值得指出的是,如果你是sed使用固定的字符串。 你也可以这样做:

 echo $PATH | cut -b 21- 

丢弃前20个字符。 同样,您可以在bash中使用${PATH:20}或在zsh中使用$PATH[20,-1]

如果要删除路径的前N个部分 ,那么当然可以使用N个调用basename ,如在glenn的答案中 ,但使用globbing可能更容易:

 path=/path/to/file/drive/file/path/ echo "${path#*/*/*/*/*/}" # file/path/ 

具体而言, ${path#*/*/*/*/*/}表示“return $path减去包含5个斜杠的最短前缀”