2010-06-16 19 views
3

問候!Bash:從兩端修剪參數

這是衆所周知的Bash參數擴展模式:

$ {參數#字}$ {參數##字}

$ {參數%字},$ {parameter %% word}

我需要切碎一部分從開始,一部分從參數尾部開始。你能爲我提供一些建議嗎?

+0

如果您提供樣本輸入和期望的輸出,您將得到很多更好的答案 – SiegeX 2010-06-16 07:41:14

+0

我有一個路徑「/.../ABC/abc.txt」,我想獲取文件「abc」的主機文件夾的名稱。 txt「,在這個例子中是」ABC「。 – 2010-06-16 08:28:05

回答

0

我不知道有一個簡單的方法可以做到這一點,而不訴諸子彈,你可能想避免效率。我只想用:

> xx=hello_there 
> yy=${xx#he} 
> zz=${yy%re} 
> echo ${zz} 
llo_the 

如果你不大驚小怪效率,只想一個班輪:

> zz=$(echo ${xx%re} | sed 's/^he//') 
> echo ${zz} 
llo_the 

請記住,這第二個方法啓動子殼 - 它不是如果腳本必須運行得很快,我會做很多事情。

+0

謝謝!我目前正在使用第一種方法的變體: DIRNAME =「./ ABC/abc.txt」DIRNAME = $ {DIRNAME#。/} DIRNAME = $ {DIRNAME%/ *。txt}但是我沒有理解爲什麼這種方法涉及子shell ... – 2010-06-16 08:25:54

+0

第一種方法不涉及子shell,它只是第二種方法。我會澄清。 – paxdiablo 2010-06-16 08:29:21

+0

是否有可能將第一種方法的兩行合併到一行中? – 2010-06-16 08:53:24

1

如果您使用的擊版本> = 3.2,則可以使用正則表達式與捕獲組匹配在一個命令中檢索值:

$ path='/xxx/yyy/zzz/ABC/abc.txt' 
$ [[ $path =~ ^.*/([^/]*)/.*$ ]] 
$ echo ${BASH_REMATCH[1]} 
ABC 

這將等效於:

$ path='/xxx/yyy/zzz/ABC/abc.txt' 
$ path=$(echo "$path" | sed 's|^.*/\([^/]*\)/.*$|\1|p') 
$ echo $path 
ABC 
0

該解決方案使用Andrey要求的內容,並且不使用任何外部工具。策略:使用參數%擴大到刪除的文件名,然後用##去除所有,但最後一個目錄:

$ path=/path/to/my/last_dir/filename.txt 

$ dir=${path%/*}  

$ echo $dir 
/path/to/my/last_dir 

$ dir=${dir##*/} 

$ echo $dir 
last_dir 
0

我會強烈建議使用bash陣列會爲他們的表現是剛剛超過3倍的速度比正則表達式匹配。

$ path='/xxx/yyy/zzz/ABC/abc.txt' 
$ IFS='/' arr=($path) 
$ echo ${arr[${#arr[@]}-2]} 
ABC 

這通過告知該陣列的每個元素由斜槓/經由IFS='/'分離的bash。我們首先通過${#arr[@]}來確定數組中有多少個元素,然後減去2並將其用作數組的索引,從而訪問數組的倒數第二個元素。