Unix-创建文件夹和文件的路径

我知道你可以用 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

有人想出解决这个问题的办法了吗?

163946 次浏览

你可以分两步来做:

mkdir -p /my/other/path/here/
touch /my/other/path/here/cpedthing.txt
#!/bin/sh
for f in "$@"; do mkdir -p "$(dirname "$f")"; done
touch "$@"

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

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

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

if [ ! -d /my/other ]
then
mkdir /my/other/path/here
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
fi

不需要 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可防止错误返回(这正是我来这里寻找的:)

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

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


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

如果你想变得有创意,你可以 发挥作用:

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

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

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

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

如果希望简单,只有一个参数代码片段:

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

正如我在 Unix 论坛上看到和测试的,这解决了这个问题

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

使用/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

我会这么做:

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

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

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

echo mkdir -p /code/temp/other/path/here && 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