2010-07-05 76 views
2

我想創建我的第一個zsh完成腳本,在這種情況下命令netcfg。zsh文件名globbling /替換

這聽起來可能聽起來有點蹩腳我在第一個障礙,免責聲明,我知道如何粗魯地做到這一點,但我尋求「ZSH WAY」來做到這一點。

我需要列出/ etc/networking中的文件,但僅列出文件,而不是目錄組件,因此我執行以下操作。

echo $(ls /etc/network.d/*(.)) 

/etc/network.d/ethernet-dhcp /etc/network.d/wireless-wpa-config 

我想要的是什麼:

ethernet-dhcp wireless-wpa-config 

所以我嘗試(原諒我naivity):

echo ${(s/*\/)$(ls /etc/network.d/*(.))} 

/etc/network.d/ethernet-dhcp /etc/network.d/wireless-wpa-config 

看來,這是不行的,我敢肯定有一定通過分裂成一個數組並獲得最後一部分來做到這一點是很聰明的方式,但正如我所說的,我完全是這樣做的。

任何建議感激地收到。

回答

0

我已經習慣於看到basename(1)剝離目錄組件;此外,您還可以使用echo /etc/network/*獲取文件列表,而無需運行外部程序ls。 (運行外部程序可能會比你想要的更慢地完成任務;我沒有找到基本名稱的zsh-builtin,但這並不意味着沒有一個。)

這是我希望的求助:

haig% for f in /etc/network/* ; do basename $f ; done 
if-down.d 
if-post-down.d 
if-pre-up.d 
if-up.d 
interfaces 
+2

'$ {param#pattern}'參數擴展是去除前綴的方法。 '$ {param%pattern}'去除後綴。 – 2010-07-05 10:18:03

7

通用注:沒有必要使用LS生成的文件名。您不妨使用echo some*glob。但是,如果你想保護可能的嵌入換行符,即使這是一個壞主意。下面的第一個例子直接插入數組中以保護嵌入的換行符。第二個使用printf生成NUL終止的數據來完成同樣的事情,而不使用變量。

這是很容易做到,如果你願意用一個變量:

typeset -a entries 
entries=(/etc/network.d/*(.)) # generate the list 
echo ${entries#/etc/network.d/} # strip the prefix from each one 

你也可以做到這一點沒有變,但多餘的東西,以單個條目隔離是醜了一點:

# From the inside, to the outside: 
# * glob the entries 
# * NUL terminate them into a single string 
# * split at NUL 
# * strip the prefix from each one 
echo ${${(0)"$(printf '%s\0' /etc/network.d/*(.))"}#/etc/network.d/} 

或者,如果你打算使用子shell無論如何(即前面的例子中的命令替換),只需cd到目錄,所以它不是glob擴展的一部分(加上,你不必重複目錄名稱):

echo ${(0)"$(cd /etc/network.d && printf '%s\0' *(.))"} 
+0

可惜我只得到+1。三個不錯的選擇,都比我的好。 :) – sarnold 2010-07-05 10:58:40

1

感謝您的建議傢伙,已經做的zsh但更多的閱讀和回來的問題幾天後,我覺得我有一個非常簡潔的解決方案,我想和大家分享你的效益。

echo $ {$(print /etc/network.d/ *(。)):T】

+0

使用進程替換是一個壞主意:它會壓縮包含空格的文件名,它更復雜,而且速度更慢。爲什麼不''echo /etc/network.d/ *(.: t)'(或者你想要的而不是'echo'的任何真正的命令)更簡單,健壯和高效? – Gilles 2017-07-10 14:21:55

2

克里斯·約翰森的答案是全程約zsh的有用信息,但它並沒有提到更簡單的解決方案,在這種特殊情況下的工作原理:

echo /etc/network.d/*(:t) 

這是使用t歷史修飾符作爲glob限定符

+0

不錯的解決方案,但是這對於文件名中的空格不起作用。 – 2017-07-10 13:26:03

+0

@AntonK globbing部分適用於任意文件名。唯一有問題的部分是'echo'。在現實世界的例子中,你不會使用'echo',你可以將列表傳遞給你想要處理文件的任何命令。 – Gilles 2017-07-10 14:18:35