2012-06-11 151 views
31

我試圖刪除部分路徑中的字符串。我有路徑:Unix刪除部分路徑

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

我想刪除的第一部分/path/to/file/drive和產生輸出:

file/path/ 

注:我有一個while循環幾條路徑,在所有同/path/to/file/drive他們,但我只是想找到'如何去除'所需的字符串。

我發現了一些例子,但我不能讓他們的工作:

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是字符串的第二部分,我清楚地做錯了什麼......也許還有一個更簡單辦法?與sed的做到這一點

回答

28

您還可以使用POSIX shell變量擴展做到這一點。

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

當變量被展開時,#..部分去掉了前導匹配的字符串;如果你的字符串已經在shell變量中,比如你使用for循環,這個特別有用。您也可以使用%...從變量末尾剝離匹配的字符串(例如,擴展名)。請參閱bash手冊頁以瞭解血腥詳細信息。

+0

謝謝...是的,我正在使用shell變量來執行此操作。這兩部分都是變量,我需要刪除的部分和完整路徑。 – esausilva

+0

優秀!但是,當字符串「從管道」進入時,我怎麼能使用它? – gromit190

+0

@Birger如果字符串來自管道,那麼你需要把它變成一個變量來使用shell變量擴展。或者在這種情況下只使用'sed'。 –

9

一種方法是

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

謝謝。這很好用 – esausilva

+0

真棒 - 我不知道sed分隔符可能是「:」(冒號)而不是「/」(斜槓)。優雅和完美的作品。 – stachyra

+0

您可以使用幾乎任何分隔符與sed,不只是/和:只要你是一致的。 –

18

如果你不想硬編碼您要移除的部分:

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

我花了2個小時看如何做到這一點。你是唯一一個發佈方式來顯示沒有硬編碼的目錄名稱的唯一方法。我需要做的是:'find/path/to/file/drive/file/* _ TST -maxdepth 0 -type d'但是我只想顯示目錄的完整路徑名稱。這做到了。 – Whitecat

+0

@Whitecat就是你想要的,閱讀「man find」,特別是「-printf」。你可以指定'-printf'%h \ n「'。請記住,它將打印每個匹配文件的目錄,因此您希望通過「uniq」進行過濾。 –

3

使用${path#/path/to/file/drive/}邪惡奧托的建議肯定是要做到這一點,典型的/最好的方法,但因爲有許多SED建議值得指出的是,如果您使用固定字符串工作,sed是過度的。您也可以這樣做:

echo $PATH | cut -b 21- 

放棄前20個字符。同樣,您可以在bash中使用${PATH:20}或在zsh中使用$PATH[20,-1]

+0

謝謝。我正在使用邪惡的奧托的答案。我想要移除的部分是固定的,但如果將腳本移動到不同的框/不同路徑,可以更改。所以,我想從變量的路徑中刪除部分使得它比計數更容易....但您提供的信息是很好知道:) – esausilva

2

如果你想刪除路徑的第N個部分,你當然可以使用ň調用basename,如glenn's answer,但它可能是更容易使用通配符:

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

具體而言,${path#*/*/*/*/*/}表示「返回$path減去包含5個斜槓的最短前綴」

32

如果要刪除某個數量的路徑組件,應該使用cut-d'/'。例如,如果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 

請注意,這些示例都使用絕對路徑,您必須四處遊覽才能使它們適用於相對路徑。

+0

令人驚歎的答案,特別是雙'rev'技巧。當我的投票帽明天褪去時,我會投票贊成。 –

+1

在原始的Unix精神中出色的信息答案,並且比{chopsquiggleSquiggle}更好:只有:shellversionyoumaynothave。 –