何百万ものファイルを特定の名前パターンを持つ別のディレクトリに移動する


10

Linuxマシンには、次の命名法の何百万ものファイルがあります。

1559704165_a1ac6f55fef555ee.jpg

最初の10桁はタイムスタンプで、その後に続く1桁_は特定のIDです。特定のファイル名IDに一致するすべてのファイルを別のフォルダに移動したい。

私はファイルのあるディレクトリでこれを試しました

find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"

ただし、次のエラーが表示されます。

bash 1559704165_a1ac6f55fef555ee.jpg: command not found

試したところ、mv ??????????_a1ac*.jpg 引数リストが長すぎるというエラーが発生しました。少なくとも15の異なるファイル名パターンがあります。それらを移動するにはどうすればよいですか。


1
bashはそれをすべて言う:それはしようと実行には、パイプの第二段階では、行の最初であるように、そのファイル名を(あなたの第二段階のパイプは次のとおりです | ??????????_a1ac*.jpg:bashは、いくつかのファイル名にそれを展開し、最初のビーイング1559704165_a1ac6f55fef555ee.jpg、あなたが終わるSI 、その2番目のパイプステージで実行しようとしました: 1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename。代わりにそのファイル名にフィルターをかけようとした(そのための以下の回答を参照)
Olivier Dulac

回答:


15

あなたは使うべきです:

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' \
-exec mv -t destination "{}" +

つまりmaxdepth 1、現在のディレクトリでサブディレクトリを検索しないことを意味します。

type f ファイルのみを検索することを意味します。

name '??????????_a1ac*.jpg' 検索しているファイルと一致するパターンです。

mv -t destination "{}" +一致したファイルを宛先に移動することを意味します。ここで+は、次のように新しい一致したファイルを以前のファイルに追加します。

mv -t dest a b c d

ここでabcdは異なるファイルです。


この人の質問に簡潔に答えてくれてありがとう。単にソリューションをダンプするのではなく、方法/内容/理由を説明できます。1人の人に1回だけ役立つのではなく、すべての人にいつでも役立つことがあります。同じ質問が過去40〜50年にわたって何度も尋ねられ、回答されてきました。問題は、よく説明されていないことです。釣りをするように男に教えてください。その間:gnu.org/software/findutils/manual/html_node/find_html/…そして、よくあることですが、公式ドキュメントよりもウィキペディアの方が便利です:en.wikipedia.org/wiki/Find_( Unix)

更新された回答を参照してください。
Prvt_Yadav

これ-tはGNU拡張機能であるため、他のタイプのUNIX派生物では使用できない場合があります。
ケビン

「二重引用符は単語の分割を防ぎます」と言うとき私はあなたがを参照していると思いますが"{}"、その場合{}、シェルによって展開されておらず、引用する必要がないことを指摘したいと思います。シェルは{}findに渡され、findは{}それを確認してパス名に置き換えます。Find execは、シェルパーサーを使用せず、独自の単語分割を行いません。引用しても害はありませんが、与えられた正当化が少し不正確であるというだけです。
jw013

@ jw013ありがとう。
Prvt_Yadav

11

あなたの命令、

find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"

すべてのファイルのリストをすべてのファイルにパイプします!

find . -maxdepth 1 -type f -name `*_a1ac*.jpg` -print0 |\
xargs  -0 -r mv -t "/home/ubuntu/ntest"

トリックを行います。


1
どうもありがとう...あなたの解決策もうまくいきました...私がどこで間違っていたかを知らせてくれてありがとう
Apricot

8

あなたはとても近いです。-nameオプションを使用してくださいfind。そして、パターンを引用することを忘れないでください。

そう

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' |xargs mv -t "/home/ubuntu/ntest"

多くの感謝...あなたの解決策もうまくいきました...私が解決策に近かったことを私に知らせてくれたことに対する追加の感謝...私のような初心者のためのその動機
Apricot

1
あなたは追加する必要があります-print0(デフォルトの代わりに:-print)見つけるために、最後の引数として、および追加-0xargsの(すなわち:への最初のオプションとしてxargs -0 mv -t "/home/ubuntu/ntest")。このようにして、あらゆる種類の奇妙なファイル名(スペースを含む、「改行」を含むなど)を処理できます。find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest" (ただし、GNUのような検索でのみ機能します)
Olivier Dulac

2

findソリューションほど「良い」ものではありませんが、mvコマンドをより細かくすることが別の有効なソリューションです。

これは4096の移動を行い、1回のmv操作で移動されるファイルの数は少なくなります。

FILEPAT=a1ac
for i in $(seq $((0x000)) $((0xfff))); 
do 
   H=$(printf '%x\n' $i)
   mv 1559704165_${FILEPAT}${H}*.jpg /home/ubuntu/ntest
done

これは、find(何らかの理由で)を持たない人にとっては巧妙なハックです。
フォレスト

-1

あなたは私はあなたがあなたにやっていると思い、同じホスト・システム上のファイルを、移動したい場合はmvrsyncより高速な選択肢が考えられます。

rsync -av --inplace -W /source/??????????_a1ac*.jpg /home/ubuntu/ntest/

--inplaceおよび-Wプロセスをスピードアップするように設定されています。

これにより別の引数リストが長すぎるエラーが発生する場合は、リストをrsync

たとえば、検索でリストを作成します

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt

そしてそれを与える rsync

rsync -av --inplace -W --files-from=/tmp/my_image_list.txt /path/to/files /home/ubuntu/ntest/

ここでのソースはです/path/to/files。これは、rsyncが与えるリストをソースとの相対として扱うためです。


重要rsyncなのはmv、ファイルが同じファイルシステム上にない場合は、よりも高速です


これは、OPが言及した同じ「引数リストが長すぎる」エラーに
該当する

@Grump、これを回避するために、OPはファイルのリストを書き込んでファイルにコピーし、find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txtそれをでrsyncに渡すことができます--files-from=/tmp/my_image_list.txt。ポイントはそれrsyncがより速いということです。ファイルが同じファイルシステムに存在しない限り、どのOPが指定していないか。
Robert Riedl

@RobertRiedl:回答を編集して、この情報を追加する必要があります。コメントは無期限にすることができます。
NickD

@NickD、私は私の答えを更新しました。
Robert Riedl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.