【问题标题】:is there a touch that can create parent directories like mkdir -p?是否可以创建像 mkdir -p 这样的父目录?
【发布时间】:2022-01-16 00:50:57
【问题描述】:

我的 .zshrc 中定义了以下两个函数

   newdir(){ # make a new dir and cd into it
        if [ $# != 1 ]; then
            printf "\nUsage: newdir <dir> \n"
        else
            /bin/mkdir -p $1 && cd $1 
        fi
    }
    
    newfile() { # make a new file, open it for editing, here specified where
        if [ -z "$1" ]; then
            printf "\nUsage: newfile FILENAME \n" 
            printf "touches a new file in the current working directory and opens with nano to edit \n\n"
            printf "Alternate usage: newfile /path/to/file FILENAME \n"
            printf "touches a new file in the specified directory, creating the diretory if needed, and opens to edit with nano \n"
        elif [ -n "$2" ]; then
            FILENAME="$2"
            DIRNAME="$1"
            if [ -d "$DIRNAME" ]; then
                cd $DIRNAME    
            else
                newdir $DIRNAME
            fi
        else
            FILENAME="$1"
        fi
    
    touch ./"$FILENAME"
    nano ./"$FILENAME"
    }

但我想知道,是否有一种类似于 mkdir -p 的触摸版本,因为它可以根据需要在一行/命令中创建父目录?

【问题讨论】:

  • 为什么不使用mkdir -p
  • @TedLyngmo 我不明白你的问题。函数 newdir 调用 mkdir -p。如果条件满足,函数newfile调用函数newdir,函数调用mkdir -p。
  • 您要求类似于mkdir -p 的东西,所以我只是想知道为什么要使用类似的东西而不是mkdir -p(如下面的Léa Gris 所示)

标签: linux bash touch zsh mkdir


【解决方案1】:

没有触摸可以创建父目录路径,所以用标准的 POSIX-shell 语法编写你自己的,也适用于 zsh:

#!/usr/bin/env sh

touchp() {
  for arg
  do
    # Get base directory
    baseDir=${arg%/*}

    # If whole path is not equal to the baseDire (sole element)
    # AND baseDir is not a directory (or does not exist)
    if ! { [ "$arg" = "$baseDir" ] || [ -d "$baseDir" ];}; then
      # Creates leading directories
      mkdir -p "${arg%/*}"
    fi

    # Touch file in-place without cd into dir
    touch "$arg"
  done
}

【讨论】:

  • 你能解释一下 ${arg##*/} 和 ${arg%/*} 是如何工作的吗?这看起来像是我想集成到我的脚本中的东西,但谷歌似乎不喜欢特殊字符的任何一种组合来自行了解更多信息。谢谢。
  • @cheechi 查看 shell 中的变量扩展
  • 我很难理解 shell 是如何扩展它的,而且我通常引用的 shell 扩展对我来说还不够简单,所以 $ for arg in $(echo /path/to/file ) ;做回声“${arg%/*}”; done /path/to 我知道它可以工作,但我会继续阅读它为什么工作,因为我期望它在这个例子中只回显“to”。(请原谅 cmets 中明显缺乏格式)
  • @cheechi 在此示例中,/* 匹配变量值末尾的“/file”,因此将其删除,留下“/path/to”。顺便说一句,$(echo /path/to/file) 只是编写/path/to/file 的一种过于复杂且容易出错的方式——$( )echo 基本上相互抵消。此外,for arg in /path/to/file 是一种过于复杂的处理 arg=/path/to/file 的方式(因为只有一个值,所以不需要循环)。
  • @GordonDavisson 我对此表示赞赏。我试图制作类似且简单的再现 for 循环,以便我可以直观地理解通配符扩展在做什么。循环是尝试用一个衬里尽可能完整地理解 touchp()。
【解决方案2】:

使用zsh,您可以:

mkdir -p -- $@:h && : >>| $@

mkdir 被赋予每个参数的“头”以创建目录(man zshexpn 表示:h 扩展修饰符的作用类似于dirname 工具)。然后,假设您没有取消设置 MUTLIOS 选项,:(不产生输出的命令)的输出将附加到文件中。

【讨论】:

  • 感谢 zshexpn 我认为这是我需要的缺失成分。当我使用 zsh 时,我主要“知道” bash 并用 bash/zsh 知识填写我不知道的内容,因为通过网络搜索找到有关 bash 的 shell 脚本信息仍然是最简单的。
猜你喜欢
  • 2016-10-02
  • 2014-11-19
  • 2020-05-08
  • 2013-12-08
  • 1970-01-01
  • 2020-02-03
  • 2011-07-08
  • 2020-05-07
  • 1970-01-01
相关资源
最近更新 更多