2012-02-26 16 views
82

Bir dosya oluşturmak için mkdir ve bir dosya oluşturmak için touch yapabileceğinizi biliyorum, ancak her iki işlemi tek seferde yapmanın bir yolu yok mu?Unix - klasör ve dosya yolu oluştur

yani klasör other var olmayan biriyle aşağıda yapmak istiyorsanız:

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

Hata:

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

herkes bunun için geçici bir çözüm olarak bir fonksiyonu ile geldi mi?

+0

Bulunan bu: http://stackoverflow.com/questions/1529946/linux-copy-and-create-destination-dir-if-it-does-not -exist –

+0

Dosya ve dizininin oluşturulmasının atomik olması şartsa, bu işlemi sunan bir dosya sistemi yazmanız gerekir. Standart Linux dosya sistemlerinde mümkün değil. –

+0

@toop Bu sorunun şu anda bir buçuk yıl olduğunu anlıyorum, ancak son zamanlarda birkaç cevap bir araya geldi. Bu tür bir şeye çok sık ihtiyacınız varsa, [yanıtımı] (http://stackoverflow.com/a/19288855/119527) yararlı bulabilirsiniz. (Kabul edilen cevaptan daha yararlı olduğunu iddia ediyorum, ama ben burada diyorum yalvarıyorum :-)) –

cevap

94

kullanın && bir kabuk doğrultusunda iki komutları birleştirmek:

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

Not: Daha önce ben ayırmak için ; kullanımını tavsiye iki komut ama @trysis tarafından işaret edildiği gibi çoğu durumda && kullanmak daha iyidir çünkü COMMAND1 başarısız olursa COMMAND2 da uygulanmayacak. (Aksi takdirde bu konulara beklediğiniz olmayabilirdi yol açabilir.)

+9

'& '' ile kullanmak için muhtemelen daha iyi, çünkü ilk komut başarısız olursa, ikinci komut hala çalışır (ve bu dizin olarak da başarısız olur) henüz mevcut değil). '&&' ile ilk komut başarısız olursa, ikinci komut çalışmaz. – trysis

+4

Kod örneği için kısa bir yol aşağıdaki gibi olabilir: 'mkdir -p/benim/diğer/yol/burada && $ _/cpredthing.txt 'ye dokunun. "$ _" Esas olarak "son komut çalıştırılan son komutta" genişler. – Sgnl

+3

@Sgnl senin tartışmanın doğru cevabıdır. Sadece daha temiz değil, daha az hataya eğilimli. – meetalexjohnson

10

Eğer iki adımda yapabilirsiniz:

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

gerek if then tablolar için ... tek bir hat üzerinde yapabiliriz usign ;

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

- iki satırda da -

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

- dizin zaten varsa -p onu ne geldi ki (hata döndürür önler e arıyorum :))

51

Tüm üst dizinleri önce yapmanız gerekir.

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

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

Ve sonra başka bir komutu gibi kullanabilirsiniz: Eğer yaratıcı almak istiyorsanız

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

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

, sen make a function can özel olarak

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

İki komutla iki adımda mı yapmalı? –

+0

Kullanmak için değiştirildi & & '' - Bu nasıl? –

+0

Bash, işlevlerde geri dönüşü destekliyor mu? –

1

(ancak Aynı dizinde hiyerarşiyi yeniden oluşturmaya çalıştığınız nadir durum), cp --parents yararlı olabilir.

/my/long kaynak dosyalarını içerir Örneğin

ve zaten var my/other, bunu yapabilirsiniz:

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

sadece 1 param snippet'iyle basit istiyorsanız:

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 
+2

Son birkaç saatlik '† çalışmasından kurtulmak istiyorsanız, bazı "rm -rf" komutlarını zahmetsizce fırlatın. - † Yani, _hours_, mantıklı bir versiyon kontrol/yedekleme politikasına bağlı olduğunuzu varsayarsak ... aksi takdirde aylar olabilir. – leftaroundabout

0

gördüğüm gibi ve bu unix forumda Test problemi

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

Do it espri çözer h/usr/bin/yükleyin:

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

Bir kaynak dosyası olmadığında:

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

Bu gem aracının büyük ölçüde dikkate alınmadığını şaşırıyorum - yükleme - daha iyi bir çözüm olduğunu gösterecektir. –

2

Bu ne yapardım geçerli:

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

Burada, $_, satır içinde gerçekleştirdiğimiz önceki komutla son bağımsız değişkeni temsil eden bir değişkendir.

Her zaman olduğu gibi, bunu gibi echo komutunu kullanarak test edebilirsiniz çıktı ne olabileceğini görmek istiyorsanız:

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

: olarak verir

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

Bir bonus olarak, brace genişletme kullanarak aynı anda birden fazla dosya yazabilirsiniz, örneğin:

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

Yine echo ile tamamen test edilebilir:

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