【问题标题】:Unix - create path of folders and fileUnix - 创建文件夹和文件的路径
【发布时间】:2012-03-16 05:06:16
【问题描述】:

我知道mkdir 可以创建目录,touch 可以创建文件,但是没有办法一次性完成这两项操作吗?

即如果我想在文件夹other 不存在时执行以下操作:

cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt

错误:

cp: cannot create regular file `/my/other/path/here/cpedthing.txt': No such file or directory

有没有人想出一个函数来解决这个问题?

【问题讨论】:

  • 如果文件及其目录的创建必须是原子的,那么您必须编写一个提供此操作的文件系统。标准 Linux 文件系统无法做到这一点。
  • @toop 我知道这个问题现在已经有一年半的时间了,但最近有几个答案被合并到这个问题中。如果您经常需要这种类型的东西,您可能会发现my answer 很有用。 (我认为比公认的答案更有用,但我不是在这里乞求代表:-))
  • @tdammers 问:“我该如何做 X?” A:“这是怎么做的”

标签: linux bash shell unix scripting


【解决方案1】:

使用&& 将两个命令组合到一个shell 行中:

COMMAND1 && COMMAND2
mkdir -p /my/other/path/here/ && touch /my/other/path/here/cpedthing.txt

注意:以前我建议使用; 来分隔两个命令,但正如@trysis 所指出的,在大多数情况下使用&& 可能会更好,因为以防COMMAND1 失败COMMAND2 不会要么执行。 (否则这可能会导致您可能没有预料到的问题。)

【讨论】:

  • 使用&& 可能更好,就像; 一样,如果第一个命令失败,第二个命令仍然会运行(并且也会失败,因为该目录还不存在)。使用&& 如果第一个命令失败,则第二个命令不会运行。
  • 代码示例的快捷方式可以是:mkdir -p /my/other/path/here && touch $_/cpredthing.txt$_ 本质上扩展为“执行的最后一个命令中的最后一个参数”。
  • @Sgnl yours 可以说是正确的答案。它不仅更干净,而且更不容易出错。
  • 我真希望touchmkdir 那样采用-p 参数。
【解决方案2】:

你需要先创建所有的父目录。

FILE=./base/data/sounds/effects/camera_click.ogg

mkdir -p "$(dirname "$FILE")" && touch "$FILE"

如果你想发挥创意,可以make a function

mktouch() {
    if [ $# -lt 1 ]; then
        echo "Missing argument";
        return 1;
    fi

    for f in "$@"; do
        mkdir -p -- "$(dirname -- "$f")"
        touch -- "$f"
    done
}

然后像任何其他命令一样使用它:

mktouch ./base/data/sounds/effects/camera_click.ogg ./some/other/file

【讨论】:

  • 改用&& - 怎么样?
  • @BЈовић Yes。 (我确实会在发布之前尝试对其进行测试。)
  • @JonathonReinhart 你确定你测试过吗?我试过supertouch "/tmp/abc/def ghi/jkl mno.txt",但失败了。所有命令dirnamemkdirtouch 都出现错误。
  • @devnull 显然不够好。该死的你的空间:-)已修复。
  • @JeremyIglehart 我喜欢它。 mktouch 是。
【解决方案3】:

使用 /usr/bin/install:

install -D /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt

当您没有源文件时:

install -D <(echo 1) /my/other/path/here/cpedthing.txt

【讨论】:

  • 我很惊讶这个 gem 工具在很大程度上被忽略了 - man install - 将表明 install 是一个更好的解决方案。
  • 你也可以使用-D /dev/null,这样我更容易记住。
【解决方案4】:

这就是我会做的:

mkdir -p /my/other/path/here &amp;&amp; touch $_/cpredthing.txt

这里,$_ 是一个变量,表示我们在行中执行的上一个命令的最后一个参数。

与往常一样,如果您想查看输出可能是什么,可以使用echo 命令对其进行测试,如下所示:

echo mkdir -p /code/temp/other/path/here &amp;&amp; echo touch $_/cpredthing.txt

输出如下:

mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt

作为奖励,您可以使用大括号扩展一次写入多个文件,例如:

mkdir -p /code/temp/other/path/here &&
touch $_/{cpredthing.txt,anotherfile,somescript.sh}

再次,完全可以使用 echo 进行测试:

mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt /code/temp/other/path/here/anotherfile /code/temp/other/path/here/somescript.sh

【讨论】:

    【解决方案5】:
    #!/bin/sh
    for f in "$@"; do mkdir -p "$(dirname "$f")"; done
    touch "$@"
    

    【讨论】:

    • 一位匿名用户建议(通过编辑)改用dirname -z "$@" | xargs -0 mkdir -p,以提高性能。 (停止潜伏,加入,看在皮特的份上!;-)
    【解决方案6】:

    您可以分两步完成:

    mkdir -p /my/other/path/here/
    touch /my/other/path/here/cpedthing.txt
    

    【讨论】:

      【解决方案7】:
      if [ ! -d /my/other ]
      then
         mkdir /my/other/path/here
         cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
      fi
      

      【讨论】:

        【解决方案8】:

        正如我在 unix 论坛中看到和测试的那样,这解决了问题

        ptouch() {
            for p in "$@"; do
                _dir="$(dirname -- "$p")"
                [ -d "$_dir" ] || mkdir -p -- "$_dir"
            touch -- "$p"
            done
        }
        

        【讨论】:

          【解决方案9】:

          不需要if then 语句... 你可以在一行上使用;

          mkdir -p /my/other/path/here;cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
          

          -- 或者两行--

          mkdir -p /my/other/path/here
          cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
          

          -- 如果目录已经存在,-p 可以防止错误返回(这是我来这里寻找的 :))

          【讨论】:

            【解决方案10】:

            在您尝试重新创建相同目录层次结构的特殊(但并非罕见)情况下,cp --parents 可能很有用。

            例如,如果/my/long 包含源文件,并且my/other 已经存在,您可以这样做:

            cd /my/long
            cp --parents path/here/thing.txt /my/other
            

            【讨论】:

              【解决方案11】:

              如果你想要简单的只有 1 个参数 sn-p :

              rm -rf /abs/path/to/file;  #prevent cases when old file was a folder
              mkdir -p /abs/path/to/file; #make it fist as a dir
              rm -rf /abs/path/to/file; #remove the leaf of the dir preserving parents 
              touch /abs/path/to/file; #create the actual file
              

              【讨论】:

              • 如果你想简单地摆脱过去几个小时的工作,请慷慨地抛出一些rm -rf 命令。 — †也就是说,小时,假设您遵守合理的版本控制/备份策略……否则,很可能需要几个月。
              • rm -rf 不应该在没有适当解释和警告的情况下被建议。
              猜你喜欢
              • 2019-05-17
              • 2012-04-22
              • 2014-03-08
              • 2023-02-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-01-27
              • 1970-01-01
              相关资源
              最近更新 更多