如何在bash完成中添加模式(用于解压缩)?


12

当我打字

unzip <tab>

我得到所有以结尾的文件的列表.zip,这是unzip命令制表符补全的标准行为。

但是,除了文件之外,我还希望bash完成以unzip结尾的列表文件。如何在本地实现此行为?.udp.zip.bashrc

Answers:


23

而不是继续评论...


complete -f -X '!*.@(zip|udp)' unzip

应该为

-f -X '!*.@(zip|udp)'
 |  |  | |||________|
 |  |  | ||     |
 |  |  | ||     +- filterpat: zip or udp
 |  |  | |+-------------  @ : Matches one of the given patterns
 |  |  | +-------------- *. : Anything+<dot>
 |  |  +----------------  ! : Negate
 |  +------------------- -X : Filter out matches in "filterpat"
 +---------------------- -f : files

换句话说:完成文件并删除所有未以.zip或结尾的文件.udp


附加功能

如果您添加-o default完成,则如果没有以或结尾的文件,则完成/匹配所有文件和目录。.zip.udp

如果添加-o plusdirs完成,则除了.zip或结尾的文件的任何匹配项,还将添加任何目录.udp

当前

使用时,complete -p unzip您将获得当前模式。

从您的评论中听起来,您听起来好像就像是在失踪+还是@在模式中失踪,例如:

# Err:
complete -f -X '!*.(zip|udp)' unzip
                   |
                   +---- Missing + or @

这意味着匹配任何以.(zip|udp)结尾的文件。例如

touch 'file_test.(zip|udp)'

还可以查看手册的这一部分:

可能例如extglob未启用。通过以下方式启用:

shopt -s extglob

shopt通过输入以下命令检查所有设置的当前状态:

shopt

功能

如果是-F something这样,则表示它使用一个名为something的函数来生成补全列表。

_filedir_xspec通常是一个Debian功能。您可能会有这样的事情:

$ cat /etc/bash_completion
. /usr/share/bash-completion/bash_completion

这意味着/usr/share/bash-completion/bash_completion获取来源。在这里,您将找到有问题功能。再往后几行,您会看到此功能/完成功能是_install_xspec由例如以下名称的功能添加的:

_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|do[ct][xm]|p[op]t[mx]|xl[st][xm])' unzip zipinfo

手动输入:


更新评论1:

–由于无效的存档或文件权限而导致不匹配。

这不应影响结果。complete仅匹配规则给定的文件,不处理文件。如果您可以使用列出它们ls,则它们应该匹配。

附带说明一下,可以通过使用完整功能添加这样的功能:

function _unzip_validated() {
    # 1. Generate list of files ending in e.g. .zip and .udp
    # 2. Validate each file and remove invalid ones from file list.
}

complete -F _unzip_validated unzip

–颜色。为什么ls区分test.ziptest.upd

这不影响completels提供的颜色由提供$LS_COLORS。尝试:

echo "$LS_COLORS" | tr : '\n' | sort

您应该看到类似的*.zip=01;31含义:

*.zip=01;31
|____| |  |
   |   |  +--- Red
   |   +------ Bold
   +---------- Files with .zip extension

*.udp 另一方面,没有与之关联的条目,因此没有着色。


下一步(应该是第一步)

  1. 打开终端,然后转到包含测试文件的目录。.zip和.udp
  2. 输入 bash --norc
  3. 输入 complete -f -X '!*.@(zip|udp)' unzip
  4. 输入 shopt -s extglob
  5. 输入 unzip <tab><tab>

结果?

另外,点击问题下方的修改,然后添加以下内容的输出:

bind -V
shopt
env

可能会有所帮助。


非常感谢您的出色冗长的解释,但仍然无法解决。complete -p unzip产生complete -f -X '!*.@(zip|udp)' unzipunzip <tab>完成名为的文件test.zip。但是,该目录还包含一个名为的文件,该文件test.upd在的制表符补全中找不到unzip。文件权限或文件长度为零的事实是否可以解释这种奇怪的行为?
Alex

@Alex:应该在空文件和有效文件以及没有权限的文件上都完成。如果将其添加到测试脚本中,行为是否相同?例如1.一些具有执行集的测试脚本:~/bin/testing,2. complete -f -X '!*.@(zip|udp)' testing,3. testing <tab><tab>
Runium

@Alex:您还可以使用以下输出更新Q shopt
Runium 2014年

extglob被激活。带有“测试”的示例zip仅再次选择文件。我注意到,该test.zip图标显示为红色,而test.upd白色显示为ls -l,带有相同的权限,ownershift和组关联的两个文件均为空。为什么ls区分test.ziptest.upd?也许这暗示了我的问题?
Alex

@Alex:添加了更新。
Runium 2014年

3

/etc/bash_completion您可能在某处采购的文件中,至少对于我的bash(v4.2.25)版本,默认完成是

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)' unzip zipinfo

尝试将整个表达式更改为

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk|udp)' unzip zipinfo

并添加到您的 .bash_profile


这不能解决我的问题。如果我这样做,其来源,unzip <tab>既不认定.zip也不是.upd文件还是其他文件。
Alex

尝试两次点击标签,看看是否有任何不同。其他完井工作是否按预期进行?例如gzip.gz文件吗?
bsd 2014年

两次点击选项卡不会更改任何内容。gunzip.gz文件一起使用时,仅选择以结尾的文件.gz,但定义也不同:complete -F _filedir_xspec gunzip
Alex

您是否将文件/etc/bash_completion作为源.bashrc
2014年

试试shopt -s extglob
Edward Falk

2

尝试在.bashrc中添加以下行:

complete -f -o default -X '!*.+(zip|udp)' unzip

似乎有了这个建议,我将找到.udp文件,但前提是没有.zip文件。如果当前目录中存在test.ziptest.udp文件,则unzip <tab>仅列出.zip文件。我希望能看到两个文件(即bash完成会给出test.)。
Alex

你确定吗?我检查了一下bash,似乎同时找到了udpzip文件。.bashrc添加行后您是否找到货源?
mkc 2014年

我在一个新的终端上重复了一下,现在unzip <tab>列出了所有文件,甚至包括以不同短语结尾的文件。现在正是我所需要的。
亚历克斯(Alex)

奇怪..我正在运行GNU bash版本4.2.25并按预期工作。您正在使用哪个版本的bash?
mkc 2014年

您能否尝试添加两条单独的行:complete -f -o default -X '!*.zip' unzipcomplete -f -o default -X '!*.udp' unzip
mkc 2014年

1

最好使用_filedir而不是“ raw” complete

理由

  • grep _filedir -r $(pkg-config --variable=completionsdir bash-completion) | wc -l
  • 波浪号(~)路径正在扩展
  • 删除目录的前缀,例如,对于/home/tux/Do<TAB><TAB>,您作为答复得到的列表将删除'/ home / tux',因此更加紧凑
  • 易于实施且更加安全

微机

_unzip_completor()
{
    # init bash-completion's stuff
    _init_completion || return

    # fill COMPREPLY using bash-completion's routine
    _filedir '@(zip|udp)'
}
complete -F _unzip_completor unzip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.