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


132

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ını içeren bir "Foo" klasörüm varsa, her iki dosyayı da "Bar" adlı bir dizine nasıl taşırım? ".Hidden" dosyası "Foo" da kaldığından, aşağıdakiler çalışmaz.

mv Foo/* Bar/

Kendin dene.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/


Bah, benimkileri yazmadan önce cevapları yenilemem gerektiğini biliyordum. Çok faydalı link.
Steven D

Ne yazık ki, bu soru burada sona ermişti çünkü SO'ya buraya ya da SU'ya taşınması gerektiğini söyledim, bu yüzden tabii ki SU'da bir yinelenen var olduğunda buraya taşındı :)
Michael Mrozek

Şahsen ben * nix'e özgü soru ve cevapların SÜ'de konu dışı olması gerektiğini düşünüyorum. Mevcut kurallarla bu iki soru arasında tonlarca içerik çarpışması yaşanıyor.
Cory Klein

Yanıtlar:


151

zsh

mv Foo/*(DN) Bar/

veya

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

( (N)Dizinin boş olmadığını biliyorsanız, bırakın .)

darbe

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

mvKomutun başarılı olmasına rağmen hata durumu döndürmesine izin vermeye istekliysen , çok daha basittir:

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

GNU bulmak ve GNU mv

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

Standart bulmak

Kaynak dizine geçmeyi sakıncası yoksa:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "$@" "$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 fazla ayrıntı.

darbe

dotglobSeçeneği ayarlayın .

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

Ayrıca, yoksayılacak iki nokta üst üste işaretli bir joker karakter şablonuna ayarlayabileceğiniz daha esnek bir GLOBIGNOREdeğişken de vardır . Ayarlanmamışsa (varsayılan ayar), kabuk dotglobayarlanmışsa değer .*boşmuş gibi ve seçenek ayarlanmamışsa değermiş gibi davranır . Kılavuzdaki Dosya Adı Genişletme bölümüne bakın . Yaygın dizinler .ve desen tarafından açıkça eşleştirilmediği ..sürece her zaman çıkarılır ..

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

ksh93

FIGNOREDeğişkeni ayarlayın . Eğer ayarlanmamışsa (varsayılan ayar), kabuk sanki değermiş gibi davranır .*. Göz ardı etmek .ve ..bunlar açıkça (Ksh 93s + 2008-01-31 devletler içinde kılavuzu eşleşmesi gerekir .ve ..hep göz ardı edilir, ancak bu doğru gerçek davranışını tarif etmez).

$ 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 kalıba dahil edebilirsiniz .

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

Dizin boşsa, genişletmenin boş görünmesi için, Ndesen eşleme seçeneğini kullanın: ~(N)@(*|.[^.]*|..?*)veya ~(N:*|.[^.]*|..?*).

zsh

dot_globSeçeneği ayarlayın .

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

.ve ..desen .açıkça öncüyle eşleşse bile asla eşleşmez .

% echo .*
..two .one

Nokta dosyalarını D glob niteleyicisiyle belirli bir düzende dahil edebilirsiniz .

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

Ekle Nboş bir dizinde boş çıkıp genişleme yapmak için glob eleme: *(DN).


Not: Eğer farklı sıralarda dosya genişleme sonuçlarını (örneğin alabilirsiniz noneizledi .oneizledi ..twosizin ayarlarınıza göre) LC_COLLATE, LC_ALLve LANGdeğişkenler.


1
Neden nullglob? mvKomutu iptal etmek (balık, csh / tcsh, zsh (olmadan (N)) yapmak veya failglob ile bash yapmak) çok mv /Bar/az mantıklı bir komut çalıştırmaktan daha anlamlı olacaktır.
Stéphane Chazelas

1
GLOBIGNORE tanımınızın yanlış ve yanıltıcı olduğunu söyleyebilirim. GLOBIGNORE'u boş olmayan bir değere ayarlamak dotglob'u açar ve dotglob'u daha sonra geri çevirseniz bile bunu eşleştirmez .ve ..asla eşleşmez (zsh, balık, pdksh ve türevleri gibi diğer hassas kabuklarda olduğu gibi). ( GLOBIGNORE=:; shopt -u dotglob; echo .*çıktı .ve ..). için GLOBIGNORE ayarlayarak .:..ya .ya :aynı etkiye sahiptir.
Stéphane Chazelas 21:16

ksh93hep görmezden .ve ..aralarında kırılmış gibi görünüyor ksh93k+(işe yaradı yerde) ve ksh93m(artık nerede çalıştığını). ksh93FIGNORE'un değerini ortamdan alacağının kötü olduğuna dikkat edin, bu nedenle FIGNORE='!(..)'örneğin bir env değişkeni yaratabilir.
Stéphane Chazelas

24
#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

itibaren man bash

dotglob Ayarlanırsa bash, 'ile' başlayan dosya adlarını içerir. Patname genişleme sonuçlarında.


Bu komutun ihmal edilmesi durumunda, eğer dizin boşsa (komut aslında amaçlandığı gibi yapılsa bile) bir hata kodu verir.
Gilles

1
@Gilles, hata daha sonra mvçağrılan dosyanın Foo/*var olmadığından şikayet etmek olacaktır . İlginçtir ki Foo, aranabilir ancak okunabilir değilse ve orada bir dosya *varsa, hiçbir hata alamazsınız, bu dosya taşınır, ancak dizin içindeki dosyalar değil. bashBir sahiptir failglobdaha gibi davranır böylece seçeneği zsh, fishya csh/ tcshve bir topak yerine olduğu gibi topak bırakarak bu sahte davranış genişletilmiş edilemez zaman bir hata ile komutu iptal.
Stéphane Chazelas 22.06.2016

7

Bu in yapmanın en basit yolu bashise

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

Ancak bu, dizinleri de harekete geçirir.

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

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


4

Bir yol kullanmaktır find:

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

-type fDosyaları bulma bulmak komutunu kısıtlar. Araştırmak gerekir -type, -maxdepthve -mindepthbir seçenek findalt dizinleri hesabına komutu özelleştirmek için. Bul uzun ama çok yararlı bir kılavuz sayfasına sahiptir .


3
Bu sadece Foo/alt dosyaları ve diğer dosyaları değil normal dosyaları taşır .
Gilles

2

Copy komutunu deneyin cp:

$ cp -r myfolder/* destinationfolder

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

rmBir klasörü kaldırmak için remove komutunu kullanabilirsiniz:

$ rm -r myfolder

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


2
Çok büyük dosyaları taşırken en iyisi değil, ama işe yarayacağını düşünüyorum.
Cory Klein

Belki yıldız yerine bir nokta kullanırsan?
vincent

1

Rsync başka bir seçenektir:

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

Bu çalışır çünkü rsync'de sondaki eğik çizgi önemlidir, sourcedirectory/dizinin içeriğini ifade ederken, dizinin içeriğini ifade eder sourcedirectory.

Bu yöntemin dezavantajı, rsync'in dizini değil sadece taşıdıktan sonra dosyaları temizlemesidir. Böylece boş bir kaynak ağacı ile kalırsınız. Bunun için geçici çözümler için, bkz:

Dosyaları taşı ve rsync ile dizinleri sil?

Dolayısıyla bu, taşıma işlemleri için en uygun olmayabilir, ancak kopyalama işlemleri için son derece yararlı olabilir.


1

Bash / fish için cevap

İşte joker karakter kullanarak yapmanın bir yolu:

.[!.]* ..?*ve dışındaki tüm gizli dosyalar ile eşleşir...

.[!.]* ..?* *ve dışındaki tüm dosyalar (gizlenmiş veya gizlenmemiş) eşleşecek...

Ve bu sorunun özel örneğini cevaplamak için ihtiyacınız olan cd foo && mv .[!.]* ..?* * ../bar

açıklama

.[!.]*İsteğe bağlı olarak herhangi bir dize ile takip eden nokta dışındaki herhangi bir karakter, ardından bir nokta ile başlayan dosya adlarıyla eşleşir . Bu yeterince yakın ancak iki noktadan başlayan dosyaları özlüyor ..foo. Bu tür dosyaları eklemek için ..?*, iki nokta ile başlayan dosya adlarıyla eşleşen, ardından isteğe bağlı olarak herhangi bir karakter izleyen herhangi bir karakter ekleriz .

Ölçek

Bu joker karakterleri aşağıdaki komutlarla test edebilirsiniz. Onları bash ve fish 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

0

Ayrıca, move komutu için dosyaları seçmek üzere geri tırnak işaretleri ile bulup grep yapabilirsiniz. Bunları mv'ye aktar.

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ı içine taşır Bar:

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

'' Dan beri Foo'daki tüm dosyaları Bar'a taşır. egrep komutunda köşeli ayraçlar olmadan bir joker karakter gibi davranır.

^Karakter maç hattının başından itibaren başlar sağlar.

egrepDesen eşleşmenin bazı detaylarını burada bulabilirsiniz .

maxdepth 1Durakları kullanmak alt dizinlere gitmeyi bulur.


0

Bu cevaptan esinlenildi :

Dosyaları kopyalamadan ...

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

Uyarılar:

  • --link-destyol mutlak veya HEDEFLE göreceli olmalıdır ( Bar örnekte)

  • /SOURCE ( Foo/örneğin) 'da koymak zorundasınız , aksi takdirde bunun yerine SOURCE klasörünü kopyalar.


0

Bunun bash için iyi çalıştığını ve kabuk seçeneklerini değiştirmeye gerek olmadığını biliyorum

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

DÜZENLE:

G-man'ın belirttiği gibi, orjinal cevabım posix uyumlu değil ve ndemou'nun yukarıdaki cevabı ile aynı. Bu, üzerinde harekete geçirilen dizelerin listelerini oluşturmak için ayraç genişlemesini kullanmak. Bu sadece cdkaynak dizine girmenize gerek olmadığı anlamına gelir . Gerçekten büyük bir değişiklik değil, ama farklı.

Örnek: Diyelim ki zaten aşağıdaki mizanpaja sahipsiniz.

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

Orijinal soru, yalnızca tek bir döneme sahip gizli dosyalardan bahsetti, ancak adın başında iki veya daha fazla döneme sahip bazı diyelim. Sadece ayraç içine ek bir ifade ekleyebilirsiniz. Daha sonra yürütebiliriz

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'de 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 da fazla ilaveli bash diş teli ile oldukça güzel şeyler yapabilirsiniz. Şık örnekler için bas korsanlarına göz atın .


1
Bu temelde, kaşlı ayraçlar eklemeniz dışında ndemou'nun cevabını çoğaltır (açıklama yapmadan). Ancak (1) cevabınız, isimleri ile başlayan dosyalarla eşleşmiyor ..ve (2) POSIX uyumlu olmak !yerine, kullanmanız gerekenler ^; yani  {*,.[!.]*},.
G-Man

@ G-Man, bunun için üzgünüm. Demek haklısın ve ndemou'nun cevabını göremediğim için kötüsün. Onlar hemen hemen aynı şey. 1. Sürümümün posix uyumlu olmadığını belirttiğiniz için teşekkür ederim. 2. Kabukun daha sonra eylem yapmak için kullanacağı dizelerin listesini oluşturmak için küme ayracı genişletmesini kullanıyorum. Bu, aynı zamanda cddosyalara etki etmek veya tüm dosyalara giden yolları ifade etmek için aynı dosya yollarını tekrar tekrar yazmak için kaynak dizine girmem gerekmediği anlamına gelir . Herhangi bir okuyucuya neden bahsettiğimin daha iyi bir resmini vermek için örneği kısa süre içinde güncelleyeceğim.
cmndr sp0ck

0

İçin minimal Linux dağıtımlarının şu işe gerektiğini. İlk önce, hepsini (gizli dosyaları özleyen) temel bir hamle yapın. Ardından, tüm gizli dosyaları taşımak (dahil .ve ..hangi olacak 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ı verir. İkinci komut olacak hep o hareket edemez diyerek bir hata üretmek .ve ... Bu nedenle, sadece hataları /dev/null(gösterildiği gibi) içine aktarın.

Buna bir astar olarak ihtiyacınız varsa, bunları yarım kolonla birleştirmeniz yeterlidir:

mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.