2010-07-05 57 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