100 dosya binlerce içeren bir klasörden nasıl taşınır?


43

Binlerce dosya içeren bir dizim var. 100 dosyadan birini (herhangi bir dosya yapacak) başka bir yere nasıl taşıyabilirim.


Ben sadece böyle web sitesine gidin böylece Unix ve Linux, onun araçlar hakkında büyük bir Web sitesi yok çünkü about.comve ben muhtemelen kullanabileceği kullanılabilir seçeneklerin listesi için başka bir web sitesinden .. ama gibi bir şey buldumtail
gsijin

Yanıtlar:


37
for file in $(ls -p | grep -v / | tail -100)
do
mv $file /other/location
done

Bu dosya adları yeni satır (varsayılan değer varsayarak boşlukları içermez varsayar $IFS), joker karakterleri ( ?, *, [) ya da başlamak -.


12
Bu yaklaşımın yalnızca dosya adlarında özel karakterler (boşluklar, yazdırılamayan karakterler, ``) yoksa işe yaradığını unutmayın. Genel bir kural olarak, çıktısını ayrıştırmayınls . Ve her zaman iki yönlü parametre ve komut değişimleri.
Gilles 'SO- şeytan olmayı'

1
Hangi bölüm 100 dosyayı oluşturur?
tshepang

3
Önceki yorumuma güncelleme yap: Gilles'un referans bağlantısını okuduktan sonra, ls'nin çıktısını ayrıştırma, emriminfind eksik olduğunu buldum . Bir argüman yanlış yerdeydi ve boş dosya adı sonları ekledim. Tek bir satırdan biraz uzun, ama bir yorumda yapabileceğim tek şey bu. İşte sabit snippet:find . -maxdepth 1 -type f \( ! -iname ".*" \) -print0 | while read -rd $'\0' file ; do mv -- "$file" /other/location/ ; done
Peter.O

@perer Sadece bir not olarak read -dkullandığınız takdirde seçeneği tüm kabuklarına taşınabilir değil, ama bashneyse, -d ''sana aynı etkiyi almalısınız -d $'\0'.
jw013

FWIW Bunun bir oneliner olarak çalışmasını istiyorsanız, ;her yeni satırın bulunduğu yere bir ekleyin .
Patrick

37

Zsh içindeki en kolayı:

mv -- *([1,100]) /other/location/

Bu hamle ilk 100 olmayan gizli dosyaları (her türlü, değişim ([1,100])için (.[1,100])için düzenli yalnızca veya dosyalara (^/[1,100])herhangi bir tür ama için dizine ) adı lexicographic sırayla. o Glob niteleyici ile farklı bir sıralama düzeni seçebilirsiniz , örneğin en eski 100 dosyayı taşımak için:

mv -- *(Om[1,100]) /other/location/

Diğer kabuklarda, erken çıkışlı bir döngüde yapabilirsiniz.

i=0
for x in *; do
  if [ "$i" = 100 ]; then break; fi
  mv -- "$x" /other/location/
  i=$((i+1))
done

Başka bir taşınabilir yol , dosyaların listesini oluşturmak ve son 100 hariç tümünü kaldırmaktır .


Güvenli kabuk genişletme için +1. Ayrıca artım çalışmasıyla daha okunabilir olur $(( i++ ))ya $[ i++ ]?

2
@hesse Bazı mermiler uygulanmaz ++ve --. Sen yazabilir : $((i+=1))yerine i=$((i+1)); Daha okunaklı olduğuna ikna olmadım.
Gilles 'SO- kötülük olmayı bırak'

1
:-D, bu cevabı gerçekten benim olduğunu düşünerek düzenledim ... Üzgünüm. Anlamı değiştirdiği için geri dönmekten çekinmeyin.
Stéphane Chazelas,

@ StéphaneChazelas Dizinleri ve sembolik bağlantıları neden hariç tuttuğunuzu merak ediyorum, soru bunun hakkında hiçbir şey söylemedi.
Gilles 'SO- kötülük' dur

@Gilles, kabul edilen cevabın, ls -p | grep -v /burada yanıt veren son bir sorusu var.
Stéphane Chazelas,

8

Eğer zsh kullanmıyorsanız:

set -- *
[ "$#" -le 100 ] || shift "$(($# - 100))"
mv -- "$@" /target/dir

Sonuncuyu (alfabetik sırayla) 100 tane hareket ettirir.


3

Aşağıdaki oneliner kabukta yardımcı olacaktır.

foreach i (`Source_Directory -type f - max-derinliği 1 | tail -100`'ü bulur); yap; {mv $ i Target_Directory}; tamam

1
Bu kabuk nedir?
phk

@phk, bu zshilk görüşte zshsentaks için oldukça yabancı görünüyor olsa bile işe yarayacaktı . Gilles, bunu yapmanın çok daha basit bir yolunu göstermiştir zsh. O zaman bile, halen kabul edilen cevaptan daha güvenilir.
Stéphane Chazelas

3

Aşağıdaki benim için çalıştı. Daha önce gönderildi, üzgünüm ama hızlı bir tarama görmedim üzgünüm.

ls path/to/dir/containing/files/* | head -100 | xargs -I{} cp {} /Path/to/new/dir


1

mmv , dosyaların toplu olarak yeniden adlandırılmasına olanak tanıyan olağanüstü bir yardımcı programdır. ( sudo apt-get install mmvYüklemek için bilgisayarımda bulunmak zorunda kaldım .) Basit kullanım örneği: .JPG uzantılı küçük bir .jpg dosyasına dönüştürmek istediğiniz bir dosya dizininin olduğunu varsayalım. Aşağıdaki komut hile yapar:

mmv \*.JPG \#1.jpg

Ters eğik çizgi, bir jokerin geldiğini göstermek için kullanılır. * / JPG, JPG uzantılı bir şeyle eşleşir. Komutun "to" bölümünde, # 1 dosyayı yeniden adlandırmak için ilk joker karakterden eşleşen metni kullanır. Elbette, dosyayı da taşımak için # 1'den önce farklı bir yol koyabilirsiniz.


2
Hedefe ulaşmak için önerdiğiniz aracı gerçekte nasıl kullanacağınızı sağlamış olsaydınız daha faydalı olurdu.
Dason

1
bir kullanım örneği ekledi
Pete

1
#!/bin/bash
c=1; d=1; mkdir -p NEWDIR_${d}
for jpg_file in *.jpg
do
if [ $c -eq 100 ]
then
d=$(( d + 1 )); c=0; mkdir -p NEWDIR_${d}
fi
mv "$jpg_file" NEWDIR_${d}/
c=$(( c + 1 ))
done

bu kodu dene


0

Bunu dene:

find /source/directory -type f -maxdepth 1 -print | tail -100 | xargs -J % mv % /other/location/

Bu yanlıştır, üç argüman iletiyorsunuz mv, sonuncusu (muhtemelen) bir dizin değil. Ve bu soruya gerçekten cevap vermiyor - asker, hepsini değil, belirli sayıda dosyayı taşımak istiyor.
Mat

Komut güncellendi.
Saumil

0

Buraya kadar geldi, ama gelen kısımlarında (99 adet) dosyaları kopyalamak gerek edildi /DIR1için /DIR2. Başkalarına yardım etmek için betiği buraya yapıştıracağım:

#!/bin/bash
# Thanks to <Jordan_U> @ #ubuntu
# 06 Dec 2014

i=0
copy_unit=98

for file in /DIR1/*; do
  cp "$file" /DIR2
  if [[ "$i" -ge "$copy_unit" ]]; then
    echo "Pausing, press enter to continue"
    read
    i=0
  fi
  ((i++))
done

0

Eğer kullanmak istiyorsanız aşağıdaki komut çalışır. ls

$ ls -rt source/* | head -n100 | xargs cp -t destination

Bu nasıl çalışıyor ??

  • ls -rt source/* - komutu göreli yolu olan tüm dosyaları listeler
  • head -n100 - ilk 100 dosyayı alır
  • xargs cp -t destination - bu dosyaları hedef klasöre taşır

0

Dosya adlarını boşluk, satırsonu, tırnak, ters eğik çizgi vb. İçeren güvenli / tutamak istiyorsanız, boş sonlandırılmış ayırıcılar kullanmanız gerekir:

find "$srcdir" -maxdepth 1 -type f -print0 | head -z -n 100 | xargs -0 -r -- mv -t "$destdir" --

EDIT2: NOT: eğer yoksa head -z( ne sebeple olursa olsun ) yukarıdakileri head -z -n 1000ile değiştirebilirsin tr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'(veya başka yollar görebilirsin )

-maxdepth 1alt dizinlerindeki dosyaları aramaktan kaçınacaktır $srcdir, bu nedenle listelenenlerin yalnızca içindeki dosyalarıdır $srcdir. listelenen her dosya arasında newline ( ) işlevini
-print0kullanır - bu, xargs içeren yeni satırları ve boşlukları içeren dosyaları işlemeye yardımcı olur. Sonlandırılmış (newline yerine ( ) sonlandırılmış) satırları satır olarak sayar . sadece bulunan ilk dosyaları listeler . Hangi komutun uygulanacağını görmek istiyorsanız , (veya ) ekleyin . "Giriş öğeler boş (tarafından sonlandırılır yerine boşluklarla arasında) karakterini ve tırnak ve ters bölü (her karakter anlamıyla alınır) özel olmayan" yayınlanmaz\0\n
head -z\0\n-n 100100find
xargs-t--verbose
xargs -0\0
xargs -rmvTaşınacak dosya yoksa (yani, findherhangi bir dosya bulamazsanız).
--Argümanların işlenmesini programın seçenekleri olarak sonlandırır, burada daha fazla ayrıntı

Örnek çıktı (bir mvkomutu çalıştırır ve yeni satırlı dosyaları kendi adlarında da kullanabilir):

$ find /tmp/t -maxdepth 1 -type f -print0 | head -z -n 100 | xargs -t -0 -r -- mv -t /tmp -- ; echo "exit codes: ${PIPESTATUS[@]}"
mv -t /tmp -- /tmp/t/file containing quotes"' then spaces /tmp/t/file containing quotes"' /tmp/t/file containing a slash n here\n /tmp/t/file containing a new line here
and continues /tmp/t/s /tmp/t/-x and -L 1. /tmp/t/of replace-str in the initi /tmp/t/-thisfile_starts_with_a_hyphen and has spaces and a -hyphen here /tmp/t/-thisfile_starts_with_a_hyphen and has spaces /tmp/t/-thisfile_starts_with_a_hyphen /tmp/t/another      with       spaces /tmp/t/one with spaces /tmp/t/c /tmp/t/a 
exit codes: 0 0 0

$ ls -1R /tmp/t
/tmp/t:
a
'another      with       spaces'
b
c
'file containing a new line here'$'\n''and continues'
'file containing a slash n here\n'
'file containing quotes"'\'''
'file containing quotes"'\'' then spaces'
'of replace-str in the initi'
'one with spaces'
s
'some dir'
-thisfile_starts_with_a_hyphen
'-thisfile_starts_with_a_hyphen and has spaces'
'-thisfile_starts_with_a_hyphen and has spaces and a -hyphen here'
'-x and -L 1.'

/tmp/t/b:
'file with spaces'

'/tmp/t/some dir':
'some file'

İçin find:

-maxdepth levels
       Descend at most levels (a non-negative integer) levels of direc‐
       tories below the starting-points.  -maxdepth 0
        means only apply the tests and actions to  the  starting-points
       themselves.
-type c
       File is of type c:

       b      block (buffered) special

       c      character (unbuffered) special

       d      directory

       p      named pipe (FIFO)

       f      regular file

       l      symbolic link; this is never true if the -L option or the
              -follow  option is in effect, unless the symbolic link is
              broken.  If you want to search for symbolic links when -L
              is in effect, use -xtype.

       s      socket

       D      door (Solaris)
-P     Never follow symbolic links.  This  is  the  default  behaviour.
       When find examines or prints information a file, and the file is
       a symbolic link, the information used shall be  taken  from  the
       properties of the symbolic link itself.
-L     Follow symbolic links.  When find examines or prints information
       about files, the information used shall be taken from the  prop‐
       erties  of  the file to which the link points, not from the link
       itself (unless it is a broken symbolic link or find is unable to
       examine  the file to which the link points).  Use of this option
       implies -noleaf.  If you later use the -P option,  -noleaf  will
       still  be  in  effect.   If -L is in effect and find discovers a
       symbolic link to a subdirectory during its search, the subdirec‐
       tory pointed to by the symbolic link will be searched.

       When the -L option is in effect, the -type predicate will always
       match against the type of the file that a symbolic  link  points
       to rather than the link itself (unless the symbolic link is bro‐
       ken).  Actions that can cause symbolic links  to  become  broken
       while  find  is executing (for example -delete) can give rise to
       confusing behaviour.  Using -L causes  the  -lname  and  -ilname
       predicates always to return false.

İçin head:

-n, --lines=[-]NUM
       print the first NUM lines instead of  the  first  10;  with  the
       leading '-', print all but the last NUM lines of each file
-z, --zero-terminated
       line delimiter is NUL, not newline

EDIT: Birisi sahip olmadıklarından bahsettihead -z , bu benim kullandığım versiyon (Fedora 25):

$ head --version
head (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie and Jim Meyering.

$ rpm -qf /usr/bin/head
coreutils-8.25-17.fc25.x86_64

İçin xargs:

-0, --null
       Input  items  are  terminated  by a null character instead of by
       whitespace, and the quotes and backslash are not special  (every
       character is taken literally).  Disables the end of file string,
       which is treated like any other  argument.   Useful  when  input
       items  might  contain  white space, quote marks, or backslashes.
       The GNU find -print0 option produces  input  suitable  for  this
       mode.
-r, --no-run-if-empty
       If the standard input does not contain any nonblanks, do not run
       the command.  Normally, the command is run once even if there is
       no input.  This option is a GNU extension.
-P max-procs, --max-procs=max-procs
       Run  up  to max-procs processes at a time; the default is 1.  If
       max-procs is 0, xargs will run as many processes as possible  at
       a  time.   Use the -n option or the -L option with -P; otherwise
       chances are that only one exec will be  done.   While  xargs  is
       running,  you  can send its process a SIGUSR1 signal to increase
       the number of commands to run simultaneously, or  a  SIGUSR2  to
       decrease  the number.  You cannot increase it above an implemen‐
       tation-defined limit (which is shown with  --show-limits).   You
       cannot  decrease  it  below  1.  xargs never terminates its com‐
       mands; when asked to decrease, it merely waits for more than one
       existing command to terminate before starting another.

       Please  note  that  it is up to the called processes to properly
       manage parallel access to shared  resources.   For  example,  if
       more  than one of them tries to print to stdout, the ouptut will
       be produced in an indeterminate order (and very likely mixed up)
       unless  the  processes  collaborate in some way to prevent this.
       Using some kind of locking scheme is one  way  to  prevent  such
       problems.   In  general, using a locking scheme will help ensure
       correct output but reduce performance.  If  you  don't  want  to
       tolerate  the  performance  difference,  simply arrange for each
       process to produce a separate output file (or otherwise use sep‐
       arate resources).
-t, --verbose
       Print  the command line on the standard error output before exe‐
       cuting it.

İçin cp:

-t, --target-directory=DIRECTORY
       copy all SOURCE arguments into DIRECTORY
-v, --verbose
       explain what is being done

-1

Bu iş parçacığının oldukça eski olduğunu biliyorum, ancak cevapları olması gerekenden daha karmaşık buldum. Bu, CentOS'ta çalıştı, ancak muhtemelen diğer dağıtımlarda da çalışması gerektiği kadar basit görünüyor.

cp `ls someDir | head -n 100` someDir100/

1
Bu işe yaramaz, çünkü çıktının başındaki ön eki lsiçermez ve somedir/dosya adı için boş veya joker karakterlerle çalışmaz veya ile başlamaz -.
Stéphane Chazelas

Yeterince adil. Aslında cp ls | head -n 100../someDir100/ yaptım / Hedef dizinin içinden ve dosya isimlerinin hiçbiri bu durumları karşılamadı. Şanslı olmak daha iyi, sonra iyi!
Jason
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.