用法:

用法:

语境

我所在的目录有 3 个文件夹。执行后,ls -1它们的顺序如下:

folder1
folder2
folder3

我想快点cd进入folder2

我能够快速编写一个cd函数folder1

这是我的职责。

f1 () {
       cd $(ls -d */|head -n 1)
}

问题

我需要一个名为 的函数f2。执行时,cds 进入folder2.


(文件夹按 排序ls -1。我正在使用zsh

答案1

默认情况下,Shell glob 按字典顺序排序,并且 Zsh 允许直接索引 glob 的结果,因此您可以执行以下操作:

cd2() {
    cd -- */([2]);       # indexing starts at one
}

在 Bash 中,您可以对数组执行相同的操作:

cd2() {
    local dirs=(*/)
    cd -- "${dirs[1]}"   # indexing starts at zero
}

两者本质上都假设至少有两个与全局匹配的项。看拘萨罗南达的回答了解处理该假设的方法。

另外,如果您使用ls别名以便给它一些标志,则排序顺序可能与 shell 的排序顺序不同。 (我在 Linux 上使用了ls别名,甚至更改了和的排序顺序。)Zsh 当然也会为您提供多种其他排序选项。ls -vF --color=auto-va_


请注意,虽然你可以使用类似于ls | head -2 | tail -1获取输出列表中的第二个文件名的方法ls,这对于带有换行符的文件名不起作用,并且涉及不是一个而是三个外部进程来执行 shell 能够自行执行的操作,因此这不是一个很好的解决方案。ls */更愚蠢的是,因为这里是它扩展了 glob,并且ls只打印出它收到的名称。看https://mywiki.wooledge.org/ParsingLs了解更多关于依赖 的输出ls可能会出现问题的信息。

答案2

使用zsh,以下内容将cd进入当前目录中的第二个目录:

cd ./*(/[2])

/括号内是 glob 的修饰符,*使其仅匹配目录名称(请参阅手册zshexpn),并[2]提取此 glob 匹配的第二个目录。

将其包装在一个函数中:

cd2nd () { cd ./*(/[2]); }

请注意,如果当前目录中没有第二个目录,这会将您带到主目录。我们可以通过首先测试第二个目录是否存在来防止这种情况:

cd2nd () { [ -d ./*(/[2]) ] && cd ./*(/[2]); }

但现在我们扩大模式两次

/bin/sh(or zsh) 中,只有一个全局匹配:

cd2nd () { set -- ./*/; [ -d "$2" ] && cd "$2"; }

这使用位置参数来保存所有子目录名称(*/仅匹配目录),测试第二个子目录是否存在,并更改该目录(如果存在)。

答案3

接受参数及其应更改为的目录号的函数

function ff()
{
    cd "$(ls -d */ | head -n $1 | tail -n 1)";
}

用法:

user@localhost:~ $ ff 2
user@localhost:~/Desktop $

解释:

  • ls -d */列出当前目录下的所有目录
  • head -n $1仅列出$1第一个目录,并且$1是我们的函数参数,因此如果您调用cc 2then$1将取值2(前两行现在正在处理)。
  • tail -n 1只选择最后一行
  • 所有这些都被发送到cd命令,因此目录被更改为正确的目录(其中有引号,因此带有空格的目录名称将被解析为一个参数)

警告!

此版本假设输入一切正常。您应该验证输入(来自用户和文件系统目录列表)以避免将来出现意外错误。

相关内容