Unix-フォルダーとファイルのパスを作成する


125

私はあなたが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ファイルシステムでは不可能です。
Peter G.

@toop私はこの質問が1年半になったことを理解していますが、いくつかの回答が最近これにマージされました。このタイプのことを非常に頻繁に行う必要がある場合は、私の答えが役立つことがあります。(私は受け入れられた答えよりも有用だと主張しますが、ここでは担当者に懇願しません:
Jonathon Reinhart 2013年

これが見つかりました:stackoverflow.com/a/8722721/29182
Ziggy

@tdammers Q:「Xを行うにはどうすればよいですか?」A:「Yの操作方法」
ヘンリーヘンリンソン、2016年

回答:


139

&&1つのシェル行で2つのコマンドを組み合わせるために使用します。

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

注:以前;は2つのコマンドを分離するためにの使用をお勧めしましたが、@ trysisで指摘されているように&&COMMAND1失敗した場合COMMAND2も実行されないため、ほとんどの状況で使用することをお勧めします。(それ以外の場合、これは予期していなかった問題につながる可能性があります。)


16
おそらく良く使用する&&、のように;最初のコマンドが失敗した場合(そのディレクトリがまだ存在していないとしても、そして失敗)、2番目のコマンドは実行されます。では&&最初のコマンドが失敗した場合、2番目のコマンドは実行されません。
トリシス

12
コード例のショートカットは次のとおりmkdir -p /my/other/path/here && touch $_/cpredthing.txtです。$_本質的に展開される「最後のコマンドの最後の引数は、実行しました」。
Sgnl

4
@Sgnlあなたのものは間違いなく正しい答えです。それはよりクリーンであるだけでなく、エラーが発生しにくくなります。
Choylton B. Higginbottom 2017

3
私は本当にそうしたようなパラメータをtouch取ったと思い-pますmkdir
Ben174

86

最初にすべての親ディレクトリを作成する必要があります。

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

それを使用する&&ように変更しました- それはどうですか?
Jonathon Reinhart

1
@BЈовић はい。(私はそれらを投稿する前にテストを試みます。)
Jonathon Reinhart 2013年

2
@JonathonReinhart本当にテストしましたか?私が試しsupertouch "/tmp/abc/def ghi/jkl mno.txt"たが失敗した。すべてのコマンドdirnamemkdirおよびtoucherrosを与えました。
devnull 2013年

2
@devnullどうやら不十分だ。スペースをくそー:-)修正。
Jonathon Reinhart 2013年

1
@JeremyIglehart好きです。mktouchそうです。
Jonathon Reinhart

24

/ 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

1
このgemツールがほとんど無視されていることに驚いています-man install-インストールがより良いソリューションであることを示します。
SC-SL

1
を使用することもでき-D /dev/nullます。
wisbucky

14

これは私がすることです:

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

13
#!/bin/sh
for f in "$@"; do mkdir -p "$(dirname "$f")"; done
touch "$@"

1
匿名ユーザーがdirname -z "$@" | xargs -0 mkdir -p、パフォーマンスのために、代わりに(編集を介して)使用を提案しました。(ピートのために潜むのをやめて、参加しましょう!;-)
jpaugh



2

私が見て、UNIXフォーラムでテストすると、これで問題が解決します

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

1

if thenステートメントの必要はありません...あなたは1行でそれを行うことができます;

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

-または2行で-

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

- -pディレクトリがすでに存在している場合、エラーが返されません(これは私がここに探していたものです:))


1

同じディレクトリ階層を再作成しようとしている特別な(珍しいことではない)場合、 cp --parents便利です。

たとえば/my/long、ソースファイルが含まれてmy/otherいて、すでに存在する場合は、次のようにできます。

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

-4

あなたが1つだけのパラメータスニペットでシンプルにしたい場合:

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

3
過去数時間の作業を単純に解消したい場合は、いくつかのrm -rfコマンドを無理やり投げてください。—†つまり、賢明なバージョン管理/バックアップポリシーを順守していると仮定すると、数時間です。それ以外の場合は、数か月になることがあります。
-leftaroundabout

1
rm -rf適切な説明と警告なしに提案するべきではありません。
-Mausy5043
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.