it-swarm-tr.com

Tüm dosyaları (gizli olanlar dahil) bir dizinden diğerine nasıl taşırsınız?

Bir dizindeki tüm dosyaları (gizli olanlar dahil) başka bir dizine nasıl taşırım?

Örneğin, içinde ".hidden" ve "notHidden" dosyaları bulunan bir "Foo" klasörüm varsa, her iki dosyayı da "Bar" adlı bir dizine nasıl taşıyabilirim? Aşağıdakiler çalışmaz, çünkü ".hidden" dosyası "Foo" da kalır.

mv Foo/* Bar/

Kendin dene.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
155
Cory Klein

Zsh

mv Foo/*(DN) Bar/

veya

setopt -s glob_dots
mv Foo/*(N) Bar/

(Dizinin boş olmadığını biliyorsanız, (N) İfadesini dışarıda bırakın.)

Bash

shopt -s dotglob nullglob
mv Foo/* Bar/

Ksh93

Dizinin boş olmadığını biliyorsanız:

FIGNORE='.?(.)'
mv Foo/* Bar/

Standart (POSIX) sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done

mv komutunun başarılı olmasına rağmen bir hata durumu döndürmesine izin vermek istiyorsanız, çok daha basittir:

mv Foo/* Foo/.[!.]* Foo/..?* Bar/

GNU bulma ve GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +

Standart bulma

Kaynak dizine geçmenin sakıncası yoksa:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "[email protected]" "$0"' ../Bar/ {} + -type d -Prune

Nokta dosyalarının bash, ksh93 ve zsh ile eşleşip eşleşmediğini kontrol etme hakkında daha ayrıntılı bilgi.

Bash

dotglob seçeneğini ayarlayın.

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero

Ayrıca yoksaymak için iki nokta üst üste işaretli bir joker karakter listesi olarak ayarlayabileceğiniz daha esnek GLOBIGNORE değişkeni vardır. Ayarlanmadıysa (varsayılan ayar), Kabuk, dotglob ayarlanmışsa değer boşmuş gibi ve seçenek ayarlanmamışsa değer .* Gibi davranır. Kılavuzdaki Dosya Adı Genişletme konusuna bakın. . Kalıpla açıkça eşleşmediği sürece, yaygın dizinler .. Ve . Her zaman atlanır.

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one

Ksh93

FIGNORE değişkenini olarak ayarlayın. Ayarsızsa (varsayılan ayar), Kabuk, değer .* Gibi davranır. . Ve .. Öğelerini yok saymak için, açıkça eşleştirilmelidirler (ksh 93s + 2008-01-31'deki kılavuz, . Ve .. 'Un her zaman yok sayıldığını belirtir , ancak bu gerçek davranışı doğru şekilde tanımlamaz).

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero

Nokta dosyalarını açık bir şekilde eşleştirerek bir desen içine ekleyebilirsiniz.

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero

Dizin boşsa genişletmenin boş kalmasını sağlamak için N desen eşleme seçeneğini kullanın: ~(N)@(*|.[^.]*|..?*) veya ~(N:*|.[^.]*|..?*).

Zsh

dot_glob Seçeneğini ayarlayın.

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero

. Ve .., Desen önde gelen . İle açıkça eşleşse bile asla eşleştirilmez.

% echo .*
..two .one

Nokta dosyalarını Dglob niteleyicisi ile belirli bir desene ekleyebilirsiniz.

% echo *(D)
..two .one none zero

Genişletmenin boş bir dizinde boş kalması için N glob niteleyicisini ekleyin: *(DN).


Not: .one Ayarlarınıza bağlı olarak dosya adı genişletme sonuçlarını farklı siparişlerde (ör. none ardından ..two Ve LC_COLLATE) Alabilirsiniz, LC_ALL Ve LANG değişken.

#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

man bash

dotglob Ayarlanmışsa, bash '.' ile başlayan dosya adlarını içerir. yol adı genişletme sonuçlarında.

24
SiegeX

Bunu bash ile yapmanın basit bir yolu

mv {Foo/*,Foo/.*} Bar/

Ama bu aynı zamanda dizinleri de taşıyacaktır.

Gizli dahil tüm dosyaları taşımak istiyor ancak herhangi bir dizini taşımak istemiyorsanız, for döngüsü ve testi kullanabilirsiniz.

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;

11
Boris Month

Bunun bir yolu find kullanmaktır:

find Foo/ -type f -exec mv -t Bar/ {} \+

-type f find komutunu dosyaları bulmakla sınırlar. -type, -maxdepth, ve -mindepthfind seçenekleri alt dizinleri hesaba katmak için komutunuzu özelleştirmek için. Bulun uzun ama çok yararlı el ile sayfa .

4
Steven D

cp kopya komutunu deneyin:

$ cp -r myfolder/* destinationfolder

cp -r, yinelemeli kopya anlamına gelir, böylece tüm klasörler ve dosyalar kopyalanır.

Bir klasörü kaldırmak için rm kaldırma komutunu kullanabilirsiniz:

$ rm -r myfolder

Daha fazlasını görün: bir dizindeki tüm dosyaları diğerine taşı .

2
ucefkh

minimal Linux dağıtımları için aşağıdakilerin çalışması gerekir. İlk olarak, tüm temel bir işlemi gerçekleştirin (gizli dosyaları kaçırır). Ardından, tüm gizli dosyaları taşıyın (. ve .. - değil aslında taşınacak).

mv /sourceDir/* /destinationDir 2> /dev/null
mv /sourceDir/.* /destinationDir 2> /dev/null

Notlar: Görünür içerik yoksa, ilk komut bir hata mesajı oluşturur. İkinci komut her zaman taşıyamayacağını söyleyen bir hata oluşturur . ve ... Bu nedenle, hataları /dev/null (gosterildigi gibi).

Buna bir astar olarak ihtiyacınız varsa, bunları bir noktalı virgül ile birleştirin:

mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
1
BuvinJ

Rsync başka bir seçenektir:

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

Bu işe yarar çünkü rsync'de sondaki eğik çizgi önemlidir, sourcedirectory/ dizinin içeriğini, sourcedirectory dizinin kendisini belirtir.

Bu yöntemin dezavantajı, rsync'in dosyaları yalnızca taşıdıktan sonra dizini değil temizleyecek olmasıdır. Böylece boş bir kaynaklı dizin ağacı kalmış. Bunun geçici çözümleri için, bkz:

Dosyaları taşı ve dizinleri rsync ile sil?

Bu, taşıma işlemleri için uygun olmasa da, kopyalama işlemleri için son derece yararlı olabilir.

1
Grumbel

bash/balık için cevap

İşte joker karakterler kullanarak bunu yapmanın bir yolu:

.[!.]* ..?*, . Ve .. Dışında tüm gizli dosyalar ile eşleşecek

.[!.]* ..?* *, . Ve .. Dışında tüm dosyalar (gizli veya değil) ile eşleşecek

Ve bu sorunun belirli bir örneğini cevaplamak için cd foo && mv .[!.]* ..?* * ../bar

açıklaması

.[!.]* Bir nokta ile başlayan dosya adlarıyla, ardından nokta isteğe bağlı olarak ve herhangi bir dize hariç herhangi bir karakterle eşleşir. Bu yeterince yakın ancak ..foo Gibi iki nokta ile başlayan dosyaları özlüyor. Bu tür dosyaları dahil etmek için, iki nokta ile başlayan ve ardından herhangi bir karakterle isteğe bağlı olarak ve ardından herhangi bir dize içeren dosya adlarıyla eşleşen ..?* .

Test

Bu joker karakterleri aşağıdaki komutlarla test edebilirsiniz. Onları bash ve balık altında başarıyla denedim. Sh, zsh, xonsh altında başarısız olurlar.

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp
1
ndemou

Bunun bash için iyi çalıştığını ve Shell seçeneklerini değiştirmeye gerek olmadığını düşünüyorum

mv sourcedir/{*,.[^.]*} destdir/

DÜZENLE:

G-man'ın belirttiği gibi, orijinal cevabım posix uyumlu değil ve yukarıdaki tek bir değişiklikle hemen hemen aynı. Bu, kaynak dizine cd girmeniz gerekmediği anlamına gelir. Gerçekten büyük bir değişiklik değil, ama farklı.

örnek: Diyelim ki zaten aşağıdaki düzeniniz var.

 $ tree -a
.
├── destdir
└── sourcedir
    ├── ..d1
    ├── ..d2
    ├── ..double
    ├── file-1
    ├── file-2
    ├── .hidden-1
    ├── .hidden-2
    ├── ...t1
    └── ...t2

Orijinal soru sadece tek bir noktaya sahip gizli dosyalardan bahsetti, ancak adın başlangıcında iki veya daha fazla noktaya sahip olduğunu varsayalım. Sadece parantez içine ek bir ifade ekleyebilirsiniz. Daha sonra,

mv sourcedir/{*,.[!.]*,..?*} destdir/

Bu, aşağıdakilere genişletilir:

mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/...t1 sourcedir/...t2 destdir/

Şimdi destdir içinde bulunan tüm dosyaları görmelisiniz:

 $ tree -a
.
├── destdir
│   ├── ..d1
│   ├── ..d2
│   ├── ..double
│   ├── file-1
│   ├── file-2
│   ├── .hidden-1
│   ├── .hidden-2
│   ├── ...t1
│   └── ...t2
└── sourcedir

4.x'te daha fazla eklemeyle bash parantezleri ile oldukça güzel şeyler yapabilirsiniz. Bazı şık örnekler için bash-hackerlar adresine bakın.

0
cmndr sp0ck

Ayrıca, move komutu için dosyaları seçmek üzere backquotes ile bulabilir ve grep yapabilirsiniz. Bunları mv'ye geçirin.

Yani Gizli dosyalar için

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

Yani

mv `find Foo -maxdepth 1 | egrep '^Foo/[.]'` Bar # mv Foo/.hidden Bar

Yalnızca seçili gizli dosyaları Bar klasörüne taşır:

mv `find Foo -maxdepth 1 | egrep '^Foo/.'` Bar # mv Foo/.hidden Foo/notHidden Bar

Foo'daki tüm dosyaları '.' Den bu yana Bar'a taşır. egrep komutunda köşeli parantezler olmadan joker karakter görevi görür.

^ Karakteri eşleşmenin satırın başından başlamasını sağlar.

egrep desen eşleşmesinin bazı ayrıntıları bulunabilir burada .

maxdepth 1 Kullanıldığında bulgunun alt dizinlere girmesi durdurulur.

0
user3192145

Esinlenen bu cevap :

Dosyaları kopyalamadan ...

rsync -ax --link-dest=../Foo/ Foo/ Bar

Uyarılar:

  • --link-dest yolu DESTINATION ile mutlak veya göreli olmalıdır (örnekte Bar)

  • / SOURCE sonrasında (Foo/)), aksi takdirde içeriği yerine SOURCE klasörünü kopyalar.

0
palindrom