如何通过CLI快速移入和移出深度嵌套的目录?


16

我们知道,使用cd <directory>会打开目录(如果存在的话)!

此外,cd ..还将使我们从当前工作目录中升级。

但是,当我们有一个路径较长的嵌套目录时/home/thina/teams/td/tech/app/release/apks,仅进入该文件夹就很累,apks而且很难返回另一个节点,在这里说/home/thina/teams

有什么方法可以跳过cdand 的输入cd ..吗?我正在使用Ubuntu 16.04。


是的 有什么方法可以跳过cdand 的输入cd ..吗?
gsthina

@GSURENDARTHINA我想您知道您可以一次返回多个级别来节省至少几次击键,例如您的情况cd ../../../../..
underscore_d

2
是否可以选择符号链接?
口袋

1
您可能还需要查看文档中的CDPATH变量bash
chepner

以防万一您没有意识到:您可以对当前工作目录中的任何目录执行“ cd <directory>”-只是不要以斜杠开头。因此,以您的示例为例,如果您的工作目录当前为“ / home / thina / teams / td / tech / app / release”,则只需键入“ cd apks”
jcadcell

Answers:


30

pushdpopd

pushd /home/thina/teams/td/tech/app/release/apks
# current directory now /home/thina/teams/td/tech/app/release/apks
popd
# current directory now what it was before pushd command

尝试help pushdhelp popd获得更多选择。没有man页面,因为pushdpopd是bash内置命令。


5
不会cd -做同样的事情吗?
edwinksl

5
@edwinksl是的,但pushdpopd能记住超过一个以前的路径。
乔斯,2016年

8
不要忘记dirspushd/ popd命令中列出目录堆栈。
Arronical

4
这些是bash内置命令,因此在bash-builtins(7)的手册页中进行了介绍。(或者也可以在bash的完整手册页中找到它们)。该信息与help pushdhelp popd您提到的(以及help dirs)相同,但我想我提到的是,以防万一人们想知道这些命令的来源。
2013年

2
@Jos您拼写错误help pusdh
Sergiy Kolodyazhnyy

16

除了已经提供的非常好的答案之外,这里还有一些cd有效使用技巧。

  • cd - 将带您回到上一个目录。
  • cd ../../..将立即带您升至3级,您可以使用..链接在一起的表示法来“向上移动” 任意数量的 目录。
  • 如果不确定要向上移动多少次,请使用cd ..,然后按箭头键向上使用bash历史记录以再次使用该命令。
  • 使用~在静置当前用户的主目录,如果你在为用户thina登录,cd ~/teams将带你到/home/thina/teams
  • 对路径使用Bash自动补全功能,Tab键将在cd命令中完成路径的一部分,如果您键入路径段的一部分,然后键入Tab,则在没有其他有效选择的情况下,该段将完成。例如,如果您键入cd /home/thina/teams/td/t然后按下Tab,则只要您在td目录中没有其他以字母t开头的文件或目录,就可以为您填充单词tech。

一起使用这些技巧可以使遍历目录的cd痛苦大大减轻。


2
加上~,尤其是如果您是root,~user将很快使您进入user的主目录。
CVn

谢谢,我没有意识到这一点,我将在下次编辑中添加它。
Arronical

9

要一次进入树的多个级别,可以使用以下功能(感谢为增强版提供必要的指导):

up ()
{
    local old="$PWD"
    for i in $(seq "${1:-1}"); do
        cd ..
    done
    OLDPWD="$old"
}

然后,您可以执行以下操作:

$ pwd
/home/thina/teams/td/tech/app/release/apks
$ up 5
cd'ing into /home/thina/teams

另外:

  • up没有参数的调用等效于cd ..由于设置时${1:-1}有替代项$11否则
  • 最后设置OLDPWD的cd ..目的是保持通常的cd -行为。

1
从技术上讲,这是一个函数,而不是别名。
Reinier Post

@ReinierPost:足够正确!我已经相应地更正了。
帕拉斯

2
意见建议:-gt代替>>是字典式的,它比较像字符串。另外,为什么不cd ..循环构建for i in $(seq "${1:-1}"); cd ..; done呢?那也可以消除if病情。
大师

@muru我同意您的gt意见,但是关于您的第二个建议,请参见答案中的最终项目符号。我感觉合理。
Oliphaunt-恢复莫妮卡

1
@Oliphaunt并不是特别困难,您只需设置OLDPWD为原始路径即可。这是完整的版本:paste.ubuntu.com/17990874
muru

7

对于长目录名,请使用具有完整路径的变量。例如,

APKS="/home/thina/teams/td/tech/app/release/apks"

那你就可以做 cd "$APKS"

至于增加x个目录,我已在此函数中定义了此功能 .bashrc

goup() # go up x number of dirs
{
  num=$1
  while [ $num -ne 0  ];do
    cd ..
    num=$( expr $num - 1   )
  done
}

要从你/home/thina/teams那里回来apks

goup  6

这是用法示例:

$> pwd
/sys/class/backlight/intel_backlight
$> goup 3
$> pwd
/sys
$> 

我想到的另一个小功能是bookmark功能,但从未使用过。

它是这样工作的:它将当前文件夹保存到某个文件,然后您可以根据该文件中的行号cd到特定目录。例:

$> cd /etc/lightdm
$> bookmark
$> cat ~/.dirsbookmarks                                                                                                  
/home/xieerqi
/sys/class/backlight
/etc/lightdm
$> cd $( awk 'NR==2' ~/.dirsbookmarks  )                                                                                 
$> pwd
/sys/class/backlight

这是函数本身:

bookmark()
{ # bookmarks current dir
  pwd >> $HOME/.dirsbookmarks
}

5

更新:有一个比autojump:更强大的工具fasd,但我并不熟悉。


我很惊讶,没有人提到autojump但其

通过从命令行维护您最常使用的目录的数据库来工作(必须先访问目录,然后才能将其跳转到。)

它基本上是@graipher构建的,具有一些其他选项。

正如我在另一个问题上提到的

cd几次到目录后(一次就足够了):

cd /home/thina/teams/td/tech/app/release/apks

您可以使用快捷方式j快速移至该位置,而不管当前位于哪个目录中:

j apks

请注意,使用路径的任何部分都可以,只要它在列表中的最高位置即可: 如果您去那里的次数多于to,j app也会带您.../apks到达.../app

我建议您不要使用自己的脚本,因为它维护得很好,为Ubuntu分发,并且具有其他简洁功能,例如跳转到child

.../td/tech $ jc apk
.../release/apks $ 

移动你apkstd,而不是其他一些apks不同的树下。


为“ fasd” +1。这真的很有用。
托马斯

4

别名

我有一个通过别名直接可用的常用目录列表。这还包括用于层次结构目录的快捷方式。

alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
alias cdwork=/home/knub/Repositories/work
alias cduni=/home/knub/University

现在,当我想升至三个级别时,我只需要输入....<Enter>就可以了!


我也喜欢这个,因为即使我起初以为“嗯,四个阶段共3个水平……”然后我想,“哦,是啊……计算机!0、1、2、3!” :D现在易于记忆,有用,以及我将要使用的东西。干杯!
P史密斯


4

打开autocd选项shopt -s autocd),这样就不必键入cd。例如,您只需要两个字符的命令..即可转到父目录。

如果要在两个目录之间导航,则可以使用切换cd -到上一个工作目录。该autocd选项不会-运行,cd -但您可以为此定义一个别名或函数。

您可以使用内建的pushd和记住堆栈中的目录popd。内置dirs列表目录堆栈(我觉得dirs -v更可读)。

如果您经常更改到特定目录的子目录,并且这些子目录具有唯一的名称,请将其添加到CDPATH变量中。但是请注意,我从未发现过CDPATH真正方便的情况。

您可以将变量设置为目录名称,然后使用进行更改$foo

Zsh 安装zsh具有bash所没有的一些不错的功能。其中一些可以通过编写执行相同功能的函数来模拟。特别是,由两参数组成的形式cd使您可以方便地更改为具有类似名称的另一个目录,例如from /home/thina/teams/td/tech/app/release/apks/com.acme/v1,running cd release betato /home/thina/teams/td/tech/app/beta/apks/com.acme/v1


2

正如我已经在UnixSE 上的一个相关问题上回答的那样,为此使用了一个名为z [github]的脚本。

它会记住您cd所在的目录,并根据频率(频率+新近度)对它们进行排名,并允许您使用其名称的某些部分更改为记住的路径之一。

cd到目录至少一次之后,您可以执行以下操作:

$ cd ~user/very/long/path/with/many/subfolders/

做就是了:

$ z sub

可以使用部分名称匹配来工作(假设您的路径中没有包含sub的其他目录,并且该目录具有较高的频率)。

我还定义了这样的函数,该函数首先尝试普通的cd,如果失败,则使用z:

function cd() {
    builtin cd "$1" 2> /dev/null || z "$1" || (echo "cd: File or Directory not found: $1" >&2 && exit 1)
}

这为您提供了两者的最佳选择。如果该文件夹位于当前目录中,或者给出了有效的完整路径,则将在该目录中进行cd,否则,它将尝试在数据库中找到一个匹配项并在其中进行cd。这消除了(小)痛苦,有时不得不使用cd(训练数据库,转到您从未去过的文件夹),有时还记得使用z(如果适用)。


您确定这cd不会干扰如何z建立经常访问的目录的数据库吗?
左右约

有何不同autojump
CiprianTomoiagă16年

@leftaroundabout:不确定,但是到目前为止,它一直运行良好。无论何时使用内置cd(我的安装程序首先尝试使用cd),z肯定都会构建数据库。但是,不确定使用z部件时是否更新了数据库。编辑:刚刚测试了在做$内置cd〜/ folder / i / have / not / been / to / yet /时是否更新了数据库。它是。
Graipher

1
@CiprianTomoiaga确实,这似乎基本上是同一件事。我使用的cd命令的覆盖也可以用于此目的。不过,自动完成功能的不同命令似乎很有趣!
Graipher

顺便说一句:我不是z的作者,只是发现它非常有用。
Graipher

1

我发现其他三种选择效果很好(尽管将来可能会pushd更多使用,但我只是了解了这一点):

  • 安排路径,这样一来您就无需cd进入深层嵌套的目录,或者更确切地说:因此,您经常需要访问的位置就在您的指尖。实现此目的的方法是使用符号链接:保持显式,层次结构清晰的目录不变,但为方便起见建立快速访问链接。

    ln -s ~/teams/td/tech/app/release/apks ~/apks

    然后,不用输入到的长路径cd,只需使用cd ~/apks和和cd ../teams(或者在该示例中更可取~/teams)返回。

  • 不要在路径之间使用单个外壳程序和cd来回切换,而要在每个需要使用的路径上运行一个外壳程序。要实现此多任务处理有多个层次:

    • 使用多个终端窗口。如果窗口位于不同的工作空间中,则效果最好。
    • 在一个窗口中使用多个选项卡。特别适合仅在某些目录中执行几个命令的情况:要返回,只需关闭终端选项卡!
    • (不是很明智的IMO,但出于完整性考虑:)请使用终端多路复用器,例如tmux
    • 只需cd在文件夹中执行的单一用途命令中启动操作,在其中执行一件事并立即将控制权交还给原始文件夹:

      $ cd /home/thina/teams/td/tech/app/release/apks
      $ some_command this_file_here
      $ cd ../../../../..

      只需做一线

      $ (cd ~/teams/td/tech/app/release/apks; some_command this_file_here)

      或同等

      $ sh -c 'cd ~/teams/td/tech/app/release/apks
      > some_command this_file_here'
  • 不要cd 在所有的,只是执行你的主目录的命令权。括号扩展可以在这里大有帮助:

    $ cd /home/thina/teams/td/tech/app/release/apks
    $ some_command this_file_here other_file_also_apks
    $ cd ../../../../..

    你可以做

    $ some_command ~/teams/td/tech/app/release/apks/{this_file_here,other_file_also_apks}

pushd是非常非常有用的。您可能想添加更多有关如何使用它的信息,以使您的答案更好。
Sergiy Kolodyazhnyy

@Serg:是的,但我本人只知道以上Jos的回答
左右左转

嗯,我明白了。好吧,这可能对将来的答案很有用。
Sergiy Kolodyazhnyy

1

推和弹出

命令pushdpopd是我的最爱。该pushd命令将记住您访问过的目录,可通过该命令查看dirs,以及当您准备向后跳转时使用popd返回。

这是使用bash函数和别名的示例:

sd ()
{
    pushd "$1" > /dev/null
}

po ()
{
    popd
}

alias d='dirs'

我经常以各种方式混合使用这些命令。

别名

经常访问的目录的另一种选择是简单地对cdor pushd命令进行别名。因此,使用您帖子中的示例:

alias cdapks='cd /home/thina/teams/td/tech/app/release/apks'
alias cdteams='cd /home/thina/teams'

组合

结合这两个想法,您甚至可以拥有:

alias sdapks='sd /home/thina/teams/td/tech/app/release/apks'
alias sdteams='sd /home/thina/teams'

这样,您在遍历目录时将具有很大的灵活性。我把cd***sd***别名手头上的事情一样DesktopDocumentsMusicDownloads,等,它是非常方便!


1

试试z.lua-一种新的cd命令,可帮助您通过学习习惯来更快地导航。

  • cd到包含foo的目录:

    z foo
  • cd到以foo结尾的目录:

    z foo$
  • 使用多个参数:

    假设以下数据库:

    10   /home/user/work/inbox
    30   /home/user/mail/inbox

    "z in"/home/user/mail/inbox作为较高权重的条目进入cd 。但是,您可以将多个参数传递给z.lua以使用其他条目。在上面的示例中,"z w in"然后将目录更改为/home/user/work/inbox

  • 带有交互式选择的cd:

    当找到多个匹配项时,使用z -i将显示一个列表:

    $ z -i soft
    3:  0.25        /home/data/software
    2:  3.75        /home/skywind/tmp/comma/software
    1:  21          /home/skywind/software
    > {CURSOR}

    然后,您可以输入数字并选择实际CD之前的位置。例如。输入3到cd/home/data/software。如果您仅按ENTER键而不输入任何内容,它将退出并保持原样。

    z.lua还支持fzf交互式选择或参数完成:

    用fzf完成

  • 快速返回父级,无需输入cd ../../..

    新选项"-b"可以快速返回bash中的特定父目录,而不必重复输入“ cd ../../ ..”:

    • (无自变量)cd进入项目根目录,该项目根目录中最近的父目录中带有.git/ .hg/ .svn

    • (一个参数)cd以关键字开头进入最接近的父级,如果找不到,请转到包含关键字的父级。

    • (两个参数):将第二个值替换为第一个值(在当前路径中)。

    ...

    让我们从别名z -b开始zb

    # go all the way up to the project root (in this case, the one that has .git in it)
    ~/github/lorem/src/public$ zb
      => cd ~/github/lorem
    
    # cd into to the first parent directory named g*
    ~/github/vimium/src/public$ zb g
      => cd ~/github
    
    # substitute jekyll with ghost
    ~/github/jekyll/test$ zb jekyll ghost
      => cd ~/github/ghost/test

希望它可以满足您的需求。


0

鱼有一些不错的设施,可以快速移动。

  • 如果键入cd右箭头enter,它将重复最近的cd。
  • 通过使用cd上箭头右箭头enter,它重复最近的cd。
  • 等等。
  • 它具有上一步和下一步的功能,通常比推送和弹出更易于使用。

此外,我将自己喜欢的目录保持链接到〜/ f,因此可以cd〜/ f / x进入〜/ foo / bar / baz / experimental-data。


0

我长期使用别名作为经常访问的目录。

我还有一个称为ccb的bash函数(用于创建cd bat文件的简称-该函数起源于dos / windows,其中.bat shell脚本ccb.bat将创建另一个.bat文件以跳转到当前目录),该函数创建/附加别名(在.bash_aliases文件中)到当前目录。

例如:$ ccb myfav将在.bash_aliases文件中使用别名myfav创建当前目录的别名,并提供.bashrc文件的源,因此该别名立即可用。

我刚刚找到了一个新的解决方案。这是一个bash功能

## USAGE : lj <your_dir>
### lj -- short for LongJump -- (kinda similar to a C function which would jump to an address outside of your current function)
function lj() {
        pushd `find . -type d -name $1 -print | head -n 1`
}

$ lj deeply_nested_dir_name

这不需要从以前的用法中学到任何东西。这可能无法解决的问题是:如果子目录树中有多个目录,名称为“ deeply_nested_dir_name”,那么它将跳至find找到的目录的第1个。

同样,此解决方案将无法转到其他目录树。

在硬编码别名和生成的别名之间以及这个新的lj()函数之间,我的大部分需求都得到了解决。

这是我的ccb()bash函数,供任何想要使用它的人使用

function ccb() {
        foo=$PWD
        echo "" >> ~/.bash_aliases
        echo "alias $1='pushd $foo > /dev/null'" >> ~/.bash_aliases
        source ~/.bashrc
}
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.