web-dev-qa-db-fra.com

Unix - crée le chemin des dossiers et des fichiers

Je sais que vous pouvez faire mkdir pour créer un répertoire et touch pour créer un fichier, mais n'y a-t-il pas moyen de faire les deux opérations en même temps?

c'est-à-dire si je veux faire ce qui suit ci-dessous lorsque le dossier other n'existe pas:

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

Erreur:

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

Quelqu'un at-il imaginé une fonction de solution de contournement?

116
toop

Utilisez && pour combiner deux commandes dans une ligne de shell:

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

Remarque: Auparavant, je recommandais d'utiliser ; pour séparer les deux commandes, mais comme l'a souligné @trysis, il est probablement préférable d'utiliser && dans la plupart des situations car dans le cas où COMMAND1 échoue COMMAND2 ne sera pas exécuté non plus. (Sinon, cela pourrait entraîner des problèmes inattendus.)

128
evotopid

Vous devez d'abord créer tous les répertoires parents.

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

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

Si vous voulez être créatif, vous pouvez créer une fonction :

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

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

Et ensuite, utilisez-le comme n'importe quelle autre commande:

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

Faites-le avec/usr/bin/install:

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

quand vous n'avez pas de fichier source:

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

Voici ce que je ferais:

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

Ici, le $_ est une variable qui représente le dernier argument de la commande précédente que nous avons exécutée en ligne.

Comme toujours, si vous voulez voir le résultat, vous pouvez le tester en utilisant la commande echo, comme suit:

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

Quelles sorties en tant que:

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

En prime, vous pouvez écrire plusieurs fichiers à la fois en utilisant l’extension d'accolade, par exemple:

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

Encore une fois, totalement testable avec 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
12
Sgnl

vous pouvez le faire en deux étapes:

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

comme j'ai vu et tester dans un forum unix cela résout le problème

ptouch() {
    for p in "$@"; do
        _dir="$(dirname -- "$p")"
        [ -d "$_dir" ] || mkdir -p -- "$_dir"
    touch -- "$p"
    done
}
2
Fabian Rios
if [ ! -d /my/other ]
then
   mkdir /my/other/path/here
   cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
fi
2
Barun Parichha

pas besoin de if then déclarations ... vous pouvez le faire sur une seule ligne usign ;

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

- ou sur deux lignes -

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

- le -p empêche les erreurs de revenir si le répertoire existe déjà (c'est ce que je suis venu chercher :))

1
tediffer3rd

Dans le cas spécial (mais pas rare) où vous essayez de recréer la même hiérarchie de répertoires, cp --parents peut être utile.

Par exemple, si /my/long contient les fichiers source et que my/other existe déjà, vous pouvez procéder comme suit:

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