数千を含むフォルダーから100個のファイルを移動する方法は?


43

数千のファイルがあるディレクトリがあります。100個のファイル(どのファイルでも可能)を別の場所に移動するにはどうすればよいですか。


私は単にのようなWebサイトにアクセスしてUnixおよびLinuxは、そのツールについての一つの大きなウェブサイトを持っていけないのでabout.com、私はおそらく使用できる利用可能なオプションのリストについては、いくつかの他のウェブサイト..しかし、のようなもの見つからないtail
外人

回答:


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

これは、ファイル名が改行(のデフォルト値を仮定して、ブランク、含まれていないと仮定し$IFS)、ワイルドカード文字を(?*[)またはで始まります-


12
この方法は、ファイル名に特殊文字(空白、印刷できない文字、「」)がない場合にのみ機能することに注意してください。一般的な規則として、の出力を解析しないlsください。また、パラメーターとコマンドの置換は常に二重引用符で囲みます。
ジル 'SO-悪であるのをやめる'

1
どのファイルが100ファイルを占めていますか?
シェパン

3
以前のコメントの更新:Gillesの参照リンクを読んだ後、lsの出力を解析しないくださいfind。コマンドが不足していることがわかりました。引数が間違った場所にあり、ファイル名の末尾にnullを追加しました。一行の長さですが、コメントでできることはこれだけです。ここでは、固定スニペットがある:find . -maxdepth 1 -type f \( ! -iname ".*" \) -print0 | while read -rd $'\0' file ; do mv -- "$file" /other/location/ ; done
Peter.O

@perer read -dオプションがすべてのシェルに移植可能ではないことに注意してください。しかし、bashとにかく使用している-d ''場合、と同じ効果が得られます-d $'\0'
jw013

FWIWこれをonelinerとして実行したい場合は;、各改行がどこにあるかを追加してください。
パトリック

37

zshで最も簡単です:

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

これは、移動(任意の型の、変更最初の100非隠されたファイル([1,100])への(.[1,100])ための定期的なファイルのみ、または(^/[1,100])任意のタイプが、用ディレクトリ)の名前辞書式順序インチ o glob修飾子を使用して別のソート順を選択できます。たとえば、最も古い100個のファイルを移動できます。

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

他のシェルを使用すると、早期終了のループで実行できます。

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

別のポータブルな方法は、ファイルのリストを作成し、最後の100を除くすべてを削除することです。


セーフシェル拡張の場合は+1。また、インクリメント操作を$(( i++ ))使用してより読みやすくなりますか$[ i++ ]

2
@hesse一部のシェルは++およびを実装しません--: $((i+=1))代わりに書くことができi=$((i+1))ます; 私はそれがより読みやすいと確信していません。
ジル 'SO-悪であるのをやめる

1
:-D、私は実際にこの答えを自分のものだと思って編集しました...ごめんなさい。それが意味を変えるので、元に戻してください。
ステファンシャゼラス

@StéphaneChazelasなぜディレクトリとシンボリックリンクを除外するのだろうと、質問はそれについて何も言わなかった。
ジル 'SO-悪であるのをやめる'

@Gilles、受け入れられた答えはls -p | grep -v /、ここにある最近の質問と同じです。
ステファンシャゼル

8

zshを使用していない場合:

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

最後の(アルファベット順で)100個を移動します。


3

シェルの次のonelinerが役立ちます。

foreach i( `Source_Directory -type f --max-depth 1 | tail -100`を検索); 行う; {mv $ i Target_Directory}; やった

1
そのシェルは何ですか?
phk

@phk、それはzsh一見zsh構文にまったく異様に見える場合でも動作するでしょう。ジルはそれをするよりずっと簡単な方法を示しましたzsh。それでも、それは現在受け入れられている答えよりもさらに信頼できます。
ステファンシャゼラス

3

次は私のために働いた。以前に投稿された場​​合は申し訳ありませんが、クイックスキャンでは表示されませんでした。

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


1

mmvは、ファイルの一括名前変更を可能にする優れたユーティリティです。(sudo apt-get install mmvコンピュータにインストールする必要がありました。)簡単な使用例:拡張子が.JPGのファイルのディレクトリがあり、小文字の.jpgに変更したいとします。次のコマンドはトリックを実行します。

mmv \*.JPG \#1.jpg

バックスラッシュは、ワイルドカードが近づいていることを示すために使用されます。* / JPGは、拡張子がJPGのすべてに一致します。コマンドの「to」部分では、#1は最初のワイルドカードの一致するテキストを使用してファイルの名前を変更します。もちろん、#1の前に別のパスを置いて、ファイルを移動することもできます。


2
目標を達成するために提案したツールを実際にどのように使用するかを提供すれば、より有益です。
デイソン

1
使用例を追加しました
ピート

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

このコードを試してください


0

これを試して:

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

これは正しくありません。3つの引数をmvに渡しますが、最後の引数は(おそらく)ディレクトリではありません。そして、それは本当に質問に答えません-質問者は、ファイルのすべてではなく、与えられた数のファイルを移動したいのです。
マット

コマンドが更新されました。
サウミル

0

私はここに来ましたが、ファイルを部分(各99)から/DIR1にコピーする必要がありました/DIR2。多分otherzを助けるためにここにスクリプトを貼り付けます:

#!/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

使用することに興味がある場合は、次のコマンドが機能します ls

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

これはどのように作動しますか ??

  • ls -rt source/* -コマンドはすべてのファイルを相対パスでリストします
  • head -n100 -最初の100ファイルを取得
  • xargs cp -t destination -これらのファイルを宛先フォルダーに移動します

0

安全にしたい/スペース、改行、引用符、バックスラッシュなどを含むファイル名を処理したい場合は、ヌル終了セパレータを使用する必要があります。

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

EDIT2: 注:あなたが持っていない場合はhead -z何らかの理由で)あなたが上に置き換えることができますhead -z -n 1000とのtr '\0\n' '\n\0' | head -n 1000 | tr '\0\n' '\n\0'(あるいは他の方法を参照してください

-maxdepth 1のサブディレクトリでファイルを探すことを避ける$srcdirため、リストされているのは内のファイルのみです$srcdir。リストされた各ファイル間でnewline()の代わりに
-print0使用します-これは、xargsで改行とスペースを含むファイルを処理するのに役立ちます。(newline()の代わりに)終了した行を行としてカウントします。最初に見つかったファイルのみがリストされます。実行する コマンドを確認する場合は、追加(または)します。「入力項目は空白ではなくヌル()文字で終了し、引用符とバックスラッシュは特別ではありません(すべての文字が文字どおりに使用されます)」は実行されません\0\n
head -z\0\n-n 100100find
xargs-t--verbose
xargs -0\0
xargs -rmv使用されます移動するファイルがない場合(つまりiffindファイルが見つかりませんでした)。
--プログラムのオプションとしての引数の処理を終了します。詳細はこちら

サンプル出力(1つのmvコマンドを実行し、名前に改行を含むファイルも処理できます):

$ 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'

のために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.

のために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:誰かに述べた彼らは持っていなかったということはhead -z、これは私が(の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

のために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.

のためにcp

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

-1

私はこのスレッドがかなり古いことを知っていますが、答えが思ったよりも複雑であることがわかりました。これはCentOSで機能しましたが、おそらく他のディストリビューションでも機能するはずです。

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

1
の出力にlsは先頭のsomedir/プレフィックスが含まれず、空白またはワイルドカード文字を含むファイル名、またはで始まるファイル名では機能しないため、これは機能しません-
ステファンシャゼル

けっこうだ。実際にls | head -n 100ターゲットディレクトリ内からcp ../someDir100/を実行しましたが、これらのケースを満たしているファイル名はありませんでした。幸運に恵まれた方が良い!
ジェイソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.