Yinelenen klasörleri “name (1)”, “name (1) (1)” vb. Yapıyla nasıl birleştirirsiniz?


1

Google Filestream, Google Drive ve Synology CloudSync'im arasında senkronizasyon yapıp her şey berbatlaştı ve "" (1) "veya" (2) "vb. Adında bir klasör adı izleyen yüzlerce yinelenen klasör kaldı ve devam ediyorum. "(1) (1) (1)" e kadar.

Bu klasörleri birleştirebilecek bir program veya komut dosyası biliyor musunuz?

Örnek üst düzey klasör yapısı:

1100 Beetledwarf - Happy ATE
1100 Beetledwarf - Happy ATE (1)
1100 Beetledwarf - Happy ATE (2)
1100 Beetledwarf - Happy ATE (3)
1100 Beetledwarf - Happy ATE (3) (1)
1100 Beetledwarf - Happy ATE (3) (1) (1)
1100 Beetledwarf - Happy ATE (4)
1100 Beetledwarf - Happy ATE (5)
1100 Beetledwarf - Happy ATE (6)

Alt klasörler bazen aynı sorunu yaşadıklarından, program veya komut dosyasının tüm alt klasörler için bu adlandırma modelini izleyen klasörleri birleştirebilmesi gerekir, örneğin:

Örnek 2. seviye klasörler:

1100 Beetledwarf - Happy ATE (6)
    Analysis
    Analysis (1)
    Smirckle_HL
    Smirckle_HL (2)
    Pending Reports
    Photos & Logos

En iyi çözüm, dosyaları kopyalamak yerine uzun zaman harcadığı için dosyaları kopyalamak yerine taşımama da izin verirdi, ancak taşıma işlemi neredeyse anında gerçekleşti.

Zaten denediğim şeylerin listesi ancak hiçbiri "name (1)" klasör yapısını (şu ana kadar söyleyebileceğim) baş edemiyor ve bunların hepsi, taşımak yerine dosyaları kopyalıyor:

  • WinMerge for Windows 10 <- google sürücü dosyalarını kopyalamaya çalışırken boğuluyor (onlar için "DOS komutu desteklenmiyor" gibi bir şey döndürüyor)
  • MacOS için Meld. <- yavaş.
  • OS X'de "ditto" komutu olan terminal <- Şimdiye kadarki en iyi seçenek.

Yardımınız için teşekkürler!


Sizi doğru anladıysam, davanızdaki dosyaları internet bağlantısı üzerinden taşımak, kopyalamakla aynı zaman alır. Örneğin dosya taşıma ile karıştırmayın içinde o çabuk, bir HD-bölüm. Bunları bölümler arasında, HD'ler arasında, PC'ler arasında vb. Taşımak genellikle çok daha fazla zaman alacaktır (bazı yapılandırmalarda istisna düşünülmez).
Albin

Teşekkürler, internet bağlantımla ilgili olanları kaldırdım, çünkü gereksiz. Windows ve Mac OS'de google dosya akışını kullanırken, dosyaları taşırsanız, dosyaları bir HD bölümü içinde taşımak gibidir: dosyaları taşırsanız, işletim sistemi genellikle dosyayı gösteren işaretleyicileri değiştirir, ancak kopyalarsanız, daha sonra işletim sistemi genellikle verileri sürücüdeki yeni bir konuma kopyalar. Bu durumda, HD internete bağlı olduğundan, kopya daha da zaman alır. Şerefe!
Josh,

Merhaba. Sorunu özellikle çözmek için bir pyhton betiği üzerinde çalışıyorum. Makul bir şekilde hazır, ancak ne yazık ki, pazartesiye kadar (önemli) son rötuşları (koruma önlemleri) yapmak için daha fazla zaman harcayamam, = / seyahat edeceğimden beri. Ondan önce bir cevaba rastlarsanız, iyi - yine de sizin için harika = D, ama hiç bir şey bulamazsanız, bunu bitirip buraya bir cevap olarak gönderebilirim =). İyi günler.
Vinícius M,

Yanıtlar:


1

Linux'ta deneyeceğim yaklaşım budur. Google Filestream, Google Drive veya Synology CloudSync ile ilgili deneyimim yok, bu yüzden çözümün uygulanıp uygulanamayacağını söyleyemem. Yine de umarım bu en azından size bazı fikirler verecektir.


Varsayımlar

  • Eğer dizin ağacında payını monte edebilirsiniz, böylece mv, cpve diğer aklı başında araçları yerel sanki dizinleri ile çalışabilir;
  • tüm (N)dizeleri çıkardıktan sonra aynı olan yolları olan dosyalar (veya dizinler) aslında aynı dosyanın (dizin) örnekleridir;
  • aynı dosyanın örnekleri yalnızca bir dosya bırakmalı;
  • aynı dizinin örnekleri, içeriklerini tek bir dizinde birleştirmelidir;
  • Burada kullandığım tüm araçları kullanabilirsiniz.

prosedür

Lütfen bir şey yapmadan önce tüm cevabı okuyunuz.

Bence bazı adımlar senaryo olarak yazılabilir, ancak çözüm oldukça deneysel olduğu için, el ile, adım adım, neler olduğuna dikkat etmek daha iyidir.

  1. cdBağlanma noktasına bir kabukta ve çağır find . | vidir -; seçtiğiniz bir metin editörü kullanın, örneğin kate, şunun gibi:

    find . | EDITOR=kate vidir
    

    Bu, editörü, her birinin önünde kendi numarası olan tüm nesnelerin bir listesiyle açacaktır. İçeriği değiştirip (geçici) dosyayı kaydettiğinizde ve düzenleyiciyi kapattığınızda, tüm değişiklikler uygulanır. Genel olarak yapabilecekleriniz:

    • dosyaları veya dizinleri taşımak (yeniden adlandırmak) için yolları değiştirmek;
    • dosyaları veya dizinleri kaldırmak için satırları silmek;
    • dosyaları değiştirmek için iki veya daha fazla numarayı değiştirin (ihtiyacınız olmaz).

    Yeni içeriğin almak istediğiniz dizin ağacını tanımladığından emin değilseniz, dosyayı kaydetmeyin.

  2. İçeriği düzenleyiciden başka bir dosyaya kopyalayın . Önemli olan, onunla çalışmak ve sonucu tekrar yapıştırmak (ve kaydetmek) yalnızca doğru yaptığınızdan emin olduğunuzda. Sonraki adımlar, açıkça aksi belirtilmedikçe yeni dosyaya atıfta bulunur.

  3. Kullanın sedveya başka bir aracı tüm kurtulmak için (N)(lider boşluğu unutmayın) dizeleri. Bu noktada "temiz" yollar bulmalısınız, çoğu bir defadan fazla gerçekleşecektir (farklı sayılarla verilir vidir).

  4. sort -k 2Bu yollara göre sıralama yapmak için kullanın . -sEski sayesinde Analysishala eskiden önce gelmelisin Analysis (1).

  5. uniq -f 1Çoğaltılan yolları bırakmak için kullanın . Şimdi herhangi bir yol yalnızca bir kez gerçekleşmelidir.

  6. Sonuçta kodlanan dizin yapısının sağlığını iki kez kontrol edin.

  7. Sonucu orijinal editöre yapıştırın, dosyayı kaydedin ve editörden çıkın. vidireksik sayılarla ilişkili nesneleri kaldıracak ve kalan sayılarla ilişkilendirilmiş nesneleri taşıyacaktır.


Test yapmak

Dizin yapısını çoğaltmak için önce bu çözümü kullanırdım:

cp -a --attributes-only /mountpoint/ /guinea_pig_dir/

ve elde edilen boş dosyalar üzerindeki prosedürü test edin. Bu, (varsa) problemleri ortaya çıkarmalı ve umarım yöntemi geliştirmeye izin vermelidir.


Olası sorunlar

  1. vidir standart olmayan bazı karakterlerle çalışmayı reddediyor.

  2. Genelde nesnelerin sırası önemlidir. Gibi nesneleri oluşturmak kaç zorluk vardır foo~ya foo~1, foo~2bir çarpışma olduğu zaman foo. Dizin ağacınızı hiçbir şekilde çarpışma oluşturmayacak şekilde "daraltacaksınız", ancak hala tüm olası senaryoları incelemedim. Gerçekten /guinea_pig_dir/ne denemelisin ve ne aldığını görmelisin. Sorun olması durumunda belkisort arasında akıllıca findve vidiryardımcı olacaktır.


1

Aşağıda bu görevi gerçekleştiren bir bash betiği verilmiştir. Örneğin, rsync eklenmiş MSYS2 Bash üzerinde çalışır. Burada bu ilgili sorudan alınmıştır:

Belirli bir sonekle dosya ve klasörleri tekilleştirmek için komut dosyası

#!/usr/bin/bash
IFS=$'\n';
set -f
#Go deepest first to deal with copies within copied folders.
for copy in $(find . -regextype posix-egrep -regex "^.*\ \([0-9]+\)\s*(\.[^/.]*)?$" | awk '{print length($0)"\t"$0}' | sort -rnk1 | cut -f2-); do
    orig=$(rev <<< "$copy" | sed -E 's/\)[0-9]+\(\ //' | rev)
    if [ "$orig" != "$copy" ]; then
        if [ -f "$orig" ]; then
            if [ -f "$copy" ]; then
                echo "File pair: $orig $copy"
                if diff -q "$orig" "$copy" &>/dev/null; then
                    echo "Removing file: $copy"
                    rm -f "$copy";
                fi
            fi           
        fi
        if [ -d "$orig" ]; then
            if [ -d "$copy" ]; then
                echo "Folder pair: $orig $copy"
                if rmdir "$copy" &>/dev/null; then
                    #If the "copy" was an empty directory then we've removed it and so we're done.
                    echo "Removed empty folder: $copy"
                else
                    #Non-destructively ensure that both folders have the same files at least.                    
                    rsync -aHAv --ignore-existing "$orig/" "$copy" &>/dev/null
                    rsync -aHAv --ignore-existing "$copy/" "$orig" &>/dev/null
                    if diff -qr "$orig" "$copy" &>/dev/null; then
                        echo "Removing folder: $copy"
                        rm -rf "$copy";
                    fi            
                fi
            fi
        fi
    fi
done
unset IFS;
set +f

Bu komut dosyasında bir başlangıç ​​dizini nasıl ayarlarım? Hem test ettiğimde hem de son sunumda sadece dosyalarımın belirli bir alt kümesinde çalışmasını isteyeceğim. Örnek: 'G: \ Sürücüm \ Deduplicate_Test_Folder' PS: İnanılmaz yanıtlar için teşekkürler!
Josh,

Sadece o klasörden başla. (Yani cdorada.)
cfp

'. 'Veya altında dosya sisteminden dosya adları okunamadı: Böyle bir dosya veya dizin' ı MSYS2 bu denenmiş ve aşağıdaki hata var: "Bul
Josh

güncelleme - hata google filestream ile ilgili görünüyor, çünkü yerel bir diskte bir klasör kullandığımda ortaya çıkmıyor
Josh

0

Aşağıdaki komut OS X'te bazı sorunlarla çalışır:

Bazen Google dokümanları kopyalanmaz ve bu nedenle klasörler fark sınamasında başarısız olur ve silinmezler. Daha sonra onlara göre diff'i manuel olarak çalıştırmalıyım, farklılıkların tüm Google docs olduğunu kontrol etmeliyim, google doc'lar orjinal klasörüne el ile taşımamalı ve yinelenen klasörleri manuel olarak silmeliyim. (Not: Bulucudan aynı belgeleri kopyalayamıyorum, bu bana çok garip geliyor çünkü daha önce google docs dosyalarını kopyaladığımı (veya seçenek + sürükleyerek) hissediyorum.)

#!/usr/bin/bash
IFS=$'\n';
set -f
#Go deepest first to deal with copies within copied folders.
for copy in $(find -E . -regex "^.*\ \([0-9]+\)\s*(\.[^/.]*)?$" | awk '{print length($0)"\t"$0}' | sort -rnk1 | cut -f2-); do
    orig=$(rev <<< "$copy" | sed -E 's/\)[0-9]+\(\ //' | rev)
    if [ "$orig" != "$copy" ]; then
        if [ -f "$orig" ]; then
            if [ -f "$copy" ]; then
                echo "File pair: $orig $copy"
                if diff -q "$orig" "$copy" &>/dev/null; then
                    echo "Removing file: $copy"
                    rm -f "$copy";
                fi
            fi           
        fi
        if [ -d "$orig" ]; then
            if [ -d "$copy" ]; then
                echo "Folder pair: $orig $copy"
                if rmdir "$copy" &>/dev/null; then
                    #If the "copy" was an empty directory then we've removed it and so we're done.
                    echo "Removed empty folder: $copy"
                else
                    #Non-destructively ensure that both folders have the same files at least.                    
                    rsync -aHAv --ignore-existing "$orig/" "$copy" &>/dev/null
                    rsync -aHAv --ignore-existing "$copy/" "$orig" &>/dev/null
                    if diff -x ‘.*’ -x 'Icon?' -qr "$orig" "$copy" &>/dev/null; then
                        echo "Removing folder: $copy"
                        trash -v "$copy"      # requires that Ali Rantakari's app is installed: aka that you have already run 'brew install trash'
                        #replaced the following: rm -rf "$copy";
                    fi            
                fi
            fi
        fi
    fi
done
unset IFS;
set +f

Not: bu çalışma, bu sayfada detaylandırıldığı gibi takılı olan aşağıdaki araçlara bağlı olabilir: https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools -in-mac-os-x /

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install coreutils
export PATH="$(brew --prefix coreutils)/libexec/gnubin:/usr/local/bin:$PATH"
brew tap homebrew/dupes
brew install binutils
brew install diffutils
brew install ed --with-default-names
brew install findutils --with-default-names
brew install gawk
brew install gnu-indent --with-default-names
brew install gnu-sed --with-default-names
brew install gnu-tar --with-default-names
brew install gnu-which --with-default-names
brew install gnutls
brew install grep --with-default-names
brew install gzip
brew install screen
brew install watch
brew install wdiff --with-gettext
brew install wget
brew install bash
brew install rsync
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.