it-swarm.cn

有没有一种单行代码可以让我创建目录并同时移入该目录?

我发现自己重复了很多:

mkdir longtitleproject
cd longtitleproject

有没有一种方法可以在一行中完成而不重复目录名称?我在这里重击。

166
methodofaction

没有内置命令,但是您可以轻松地编写一个函数,依次调用mkdircd

mkcd () {
  mkdir "$1"
  cd "$1"
}

将此代码放入您的~/.bashrc文件中(对于ksh用户,则为~/.kshrc;对于zsh用户,则为~/.zshrc)。它定义了一个名为mkcd的函数。 "$1"在运行时将被函数的参数替换。

这个简单的版本有几个缺陷:

  • 您不能一次创建子目录链。修复:将-p选项传递给mkdir。 (这可能会或可能不会很理想,因为它会增加错别字的风险,例如,当您想在现有mydierctory中创建newsub时,mkcd mydierctory/newsub会很高兴地创建mydirectorymydierctory/newsub。)
  • 如果参数以-开头,而不仅仅是-,则mkdircd会将其解释为一个选项。如果只是-,则cd会将其解释为$OLDPWD。如果它是+后跟0或多个数字,则zsh中的cd会将其解释为目录堆栈中的索引。您可以通过在参数前传递--来解决第一个问题,但不能解决其他两个问题。您可以通过在参数的相对路径前添加./来解决所有这些问题。
  • mkdir不跟随CDPATH,但是cd跟随,因此,如果您将CDPATH设置为不以.开头的值(这是公认的某种不寻常的配置),那么cd可能会将您带到与以下目录不同的目录刚刚创建的那个。在相对路径前面加上./可以解决此问题(这会导致CDPATH被忽略)。
  • 如果mkdir失败,它将尝试执行cd。修复:使用&&分隔两个命令。

仍然相当简单:

mkcd () {
  case "$1" in /*) :;; *) set -- "./$1";; esac
  mkdir -p "$1" && cd "$1"
}

此版本仍然有可能使cd进入与在一个Edge情况下创建的mkdir不同的目录:如果mkcd的参数包含..并通过符号链接。例如,如果当前目录是/tmp/here,而mylink是到/somewhere/else的符号链接,则mkdir mylink/../foo创建/somewhere/else/foo,而cd mylink/../foo更改为foo。在参数中查找符号链接是不够的,因为Shell还会在其自己的当前目录中跟踪符号链接,因此cd /tmp/mylink; mkdir ../foo; cd ../foo不会更改为新目录(/somewhere/else/foo),而是会更改为/tmp/foo。解决此问题的方法是让cd内置函数首先解析所有..路径组件(如果foo不存在,则不使用foo/..,因此mkdir永远不需要看到任何..)。

我们来看看这个健壮的版本:

mkcd () {
  case "$1" in
    */..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
    /*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
    /*) mkdir -p "$1" && cd "$1";;
    */../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
    ../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
    *) mkdir -p "./$1" && cd "./$1";;
  esac
}

(练习:为什么我在第一个cd调用中使用子外壳?)

如果mkdir失败,我想确保不要更改当前目录。如果命令行管理程序没有权限更改为当前目录,则使用cd-或$ OLDPWD进行更改是不够的。另外,调用cd会更新OLDPWD,因此我们只希望执行一次(或恢复OLDPWD)。


还有一些不太专业的方法,不必从上一行重新输入Word:

  • 输入cd,然后 Esc. (要么 Alt+.)以插入上一个命令的最后一个参数。
  • cd !$对上一个命令的最后一个参数执行cd
  • 按 Up 调用前一个命令行,然后对其进行编辑以将mkdir更改为cd
172

这是您需要的一线。无需其他配置:

mkdir longtitleproject && cd $_

以bash表示的$_变量是上一个命令的最后一个参数。在这种情况下,您刚刚创建的目录的名称。如man bash中所述:

_         At  Shell  startup,  set to the absolute pathname used to invoke
          the Shell or Shell script being executed as passed in the  envi‐
          ronment  or  argument  list.   Subsequently, expands to the last
          argument to the previous command, after expansion.  Also set  to
          the  full  pathname  used  to  invoke  each command executed and
          placed in the environment exported to that command.  When check‐
          ing  mail,  this  parameter holds the name of the mail file cur‐
          rently being checked."$_" is the last argument of the previous command.

使用cd $_而不是cd !$来检索上一个命令的最后一个参数,因为cd !$给出了上一个命令的最后一个参数在Shell历史中

cd ~/
mkdir folder && cd !$

你最终回家(或〜/)

cd ~/
mkdir newfolder && cd $_

你最终在家里的新文件夹下! (或〜/ newfolder)

151
Jesús Carrera

我几乎不可能编写这种行为,因为我几乎每小时都要输入以下内容...

$ mkdir someDirectory<ENTER>
$ cd !$

bash好心替代!$和最后一行的最后一个单词;即您输入的长目录名称。

此外,在这种情况下,文件名补全是您的朋友。如果您的新目录是文件夹中的唯一文件,请快速双击 TAB 会在不重新输入的情况下为您提供新目录。

虽然bash允许您编写诸如其他答案所示的常见任务的脚本很酷,但我认为最好学习bash必须提供的命令行编辑功能,这样当您在另一台计算机上工作时,也不会错过语法您的自定义脚本提供的糖。

30
Rob

按照 您在Shell配置文件上进行了哪些自定义以提高生产率? ,这是我的方法:

# make a directory and cd to it
mcd()
{
    test -d "$1" || mkdir "$1" && cd "$1"
}

这意味着如果目录已经存在,它也可以工作。

17
Mikel

如果使用Oh My Zsh,则有一个名为take的命令可以执行此操作。看起来像这样。

take myfolder

我实际上是偶然发现的。我只是看了一下,它被列在Oh My Zsh GitHub wiki的 this cheatsheat 上。这是一个非常有用的命令,显然很容易创建自己。

16
Jordan Harris

或者,您可以即时创建一个简短的变量,并使用两次x = longproject ; mkdir $x ; cd $x-我承认比使用shellscript函数还更长:)

3
sakisk

我制作了一个脚本,先创建目录,再创建cd,然后给它起别名。这是我要描述的要点。

https://Gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be

0
Marcus Rehn

这是一个值得一提的细微变化:

function mkdir() {
    local dir=$1
    command mkdir "$dir"  &&  cd "$dir"
}

将此添加到您的~/.bash_profile中,然后您就可以照常使用mkdir(一旦您已经source添加了它),除了现在它将运行上面的函数而不是标准函数mkdir命令。

请注意,这不会按照接受的 Gills的答案 验证输入,而是演示了如何(有效)覆盖内置函数。

摘自文档 (略述):

command mkdir [args]使用mkdir运行args,而忽略了任何名为mkdir的Shell函数。仅执行Shell内置命令或通过搜索PATH找到的命令。如果有一个名为ls的Shell函数,则在该函数中运行command ls将执行外部命令ls而不是递归调用该函数

我相信builtin的效果与command相似。

0
Arj

向BASH,ZSH或KSH添加辅助功能

一行创建mkcd命令到您的环境

echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
0
Proximo