「mv」がファイルのコレクションを単一の通常のコレクションに移動しないようにするにはどうすればよいですか?


17

愚かな間違いで、オーディオコレクションのほんの一部を失いました。:-(
残念ながら、かなり最近のバックアップがありましたが、それでもいらいらしていました。本当にあなたを除いて、いたずらをしている他の犯人はmv、次のように表示されます:

オーディオファイルには特定のスキームがありました。

ARTIST - Some Title YY.mp3

ここYYで、2桁の年の指定です。

mkdir 90<invisible control character>

(現時点では、目に見えない3分の1の余分な文字を実際に入力したことを知りませんでした...!)
1つのディレクトリにすべてを入れるのではなく、1990年代のすべての音楽を1つのディレクトリに入れたいと思いました。だから私は入力しました:

find . -name '* 9?.mp3' -exec mv {} 90 \;

何が起こったのかを理解するのはそれほど難しくありませんか?:->
(悲惨な)結果は、'90 something '(何かが "見えない"制御文字である)と呼ばれる新しい空のディレクトリと、'90 ' と呼ばれる単一のファイルでn回上書きされました。

すべてのファイルがなくなった。:-(((明らかに)

ウィッシュmvただろうにチェック:先「ファイル」の署名が(* NIX上で覚えているかどうかを時間内にすべてですAファイルで始まる)d------(例えばdrwxr-xr-x)。そして、もちろん、宛先まったく存在するかどうか。あなたは、単に前述のシナリオのバリエーションがあるのを忘れmkdir最初のディレクトリが。(もちろん、あなたはそれがそこにあると仮定しました...)

大文字のWで始まるペット嫌いのOSでさえ、これを行います。宛先のタイプ(ファイル?ディレクトリ?)を指定するように求められた場合でも指定するように求められます。

したがって、* NIXersは、mvこれらの種類の最も望ましくない驚きを避けるために、「スクリプトレット」を作成する必要があるのではないかと考えています。


2
すべてのファイルが削除されたわけではありません。少なくとも1つ.mp3は、という名前90でそこに存在している必要があります。これは、バックアップがないものである可能性があります。
アントン14年

2
へえ、あなたはユーモアの冷笑的な感覚を持っている、あなたはあなたにナットをつけます!:-Pまあ、それは私のOPでは太字で「1つのファイル」と呼ばれるファイルでした。:)
構文エラー14年

2
mvここでは問題ではありません。技術的には、一連のファイルを移動していることを知りません。mvファイルごとに1回実行しています。それがどのようにfind -exec ;機能するかです。あなたが使用していた場合にはfind -exec +(コメントのいくつかのように)mv なり、それは複数の引数を持ってすぐに悲鳴を上げてきました。
エタンReisner 14年

mv単一のファイルごとに実行することは、最初は少し考えられていないように見えますが、ソースファイルがさまざまなサブディレクトリに散らばると、それは(前述したように)唯一の正解です。私のテストケースでは、ソースファイルがすべて1つのディレクトリにあったということは、それが私の実際のテストケースであることを意味しません。それは実際には単純化に過ぎません。これについては後で自分で簡単に説明することができるからです。さらに、質問の長さが短縮されるため、質問の読み取り時間が短縮されます。:)
構文エラー14年

mv宛先が存在することを要求するのはなぜですか?mv oldfile newfileファイルの名前を変更する方法であり、newfile既に存在してディレクトリになることを期待するのはばかげています。
バーマー14年

回答:


37

/ファイルをディレクトリに移動する場合は、宛先にa を追加できます。ディレクトリが存在しない場合、エラーが表示されます。

mv somefile somedir/
mv: cannot move ‘somefile’ to ‘somedir/’: Not a directory

ディレクトリが存在する場合、ファイルをそのディレクトリに移動します。


4
どうもありがとうございます!それが私の将来の命の恩人になるはずです。あなたに貸しがある。(メモとして、私の友人が数年前にまったく同じ過ちを犯したので、私は一人ではないように感じます。)
syntaxerror 14年

1
また、特定のシェルを使用する場合、ファイル名を自動補完するTabオプションがあります。ディレクトリ名がよくわからず、最近のような混乱を避けたい場合は、1つまたは2つのディレクトリ名とHIT TABを打ち込んでください。そして、あなたはそれが....そこに理由はオートコンプリートプット、それが存在していることを、確認することができます
Andyzスミス

@AndyzSmithまあ、それはまさにそれです。TABを複雑なディレクトリまたはパスにのみ使用し、2文字タイプのものには使用しないのが私の習慣であると呼ぶかもしれません。今後。
構文エラー14

20

GNU coreutilsにmvは、ディレクトリ-t/ に移動することを指定するオプションが既にあります--target-directory。そのオプションへの引数が存在しない場合、mvすべてのファイルを同じファイル名に移動する代わりに文句を言います。

私はあなたの発動機を次のように書いたでしょう。

find . -name '* 9?.mp3' -exec mv -t 90 {} +

+代わりにを使用することに注意してください\;。可能な限り多くのファイル名を一緒にグロビングして、実行を高速化します。


ありがとう。(しかし、それは再びそれらのGNU主義の1つではありません。)
syntaxerror 14年

2
@構文エラー。それはGNUismです。POSIXly:find . -name '* 9?.mp3' -exec sh -c 'exec mv "$@" 90/' sh {} +
ステファンChazelas

この最もすてきなワンライナーをありがとうございました!私があなたに与えた+5だと思ってください。:)多くの試行錯誤の試みを不必要にします。単純にPOSIXであるマシン上にいる必要があり(まれにしか発生しません)、すぐに次の問題が発生します。:)
構文エラー14年

1
@syntaxerrorこの回答で問題が解決した場合、左の投票数の下にあるチェックマークをクリックしてください。これは、問題が解決されたことを意味し、サイトで感謝が表明されていることを意味します。他の回答された質問のほんの一部が回答を受け入れているのを見ました。あなたもそれらを明らかにしたいと思うかもしれません。
アントン14年

いいえ、それは単に目的です。答えを受け入れるまで、私は頻繁に数週間、時には2ヶ月待ちます。その理由は、非常に知識のある人の中には非常に負荷の高いスケジュールがあり、数週間後に(通常は最高の)答えを出す時間しか見つからない場合があるためです。だから、彼らが立ち寄るのを待つのはいつも敬意を表します。まあ、もし本当にそうならなければ、私はチェックマークを打つことをheしません、確かに。その上、なぜ一部の人々がSE +そのフレーバーにいつもそんなに急いでいるのかわかりません。簡単にできます 銃をジャンプしないでください。:)これはあなたの上司があなたに押し付けているわけではありません。
構文エラー14年

10

また、将来的に誤って上書きすることを一般的に計画している場合は、の-iオプションがありますmv。私は個人的にどんな欠点も考えられません

alias mv='mv -i'

何かを上書きする必要がある場合は、-fオプションを渡すだけです。

エイリアスは、コマンドを対話型シェルに直接入力した場合にのみ有効になりますfind。あなたは走ったかもしれない

find . -name '* 9?.mp3' -exec mv -i {} 90 \;

そしてmv、既存のファイルを上書きしようとした場合、プロンプトが表示されます。


4
または-おそらく知らなかったように-の代わりに ´\ mvを入力してくださいmv。このあまり知られていない「トリック」により、コマンドにバックスラッシュが付加されエイリアス定義が無視されます。
構文エラー14年

もちろん、実際にについて話している場合は、エイリアスを調べないためfind ... -exec mv ...、作成~/bin/mv(または他の適切なディレクトリ)して作成する必要があります。/bin/mv -i "$@"find ... -exec
G-Manは「Reinstate Monica」と言います14

この場合、私は好むでしょうenv mv。タイピングが少ない。:)私のローカルキーボードレイアウトでは、スラッシュを入力するにはShiftキーを押す必要があるため、「スラッシュのない」バージョン(該当する場合)を常に優先します。
構文エラー14年

1
@syntaxerror:ところで、(新しいコメントで)コメントに応答するとき、「@ G-Man」のように「@」が前に付いた著者の名前に言及するのが一般的です。そのように私は通知されます。(ジェニーDのコメントで通知されたので、最後のコメントに半時間で返信できました。)短縮するか、「@StéphaneChazelas」のように名前全体(スペースなし)を使用できます。投稿の作成者には、その投稿へのコメントが自動的に通知されます。このヘルプページのコメントで返信の段落を参照してください
G-マンは「元に戻すモニカ言う

1
申し訳ありませんが、1日間インターネットにアクセスできませんでした。@ G-Man mvの最初の場所に個人版を持っている$PATHと、よりクリーンなソリューションになることに同意します。一方mv、インタラクティブシェルでは、主に不注意で偶然に発生します(高速で発生するため)。ループやシェルスクリプトfindなど、より複雑なものを作成する瞬間に、何かを壊さないようにするためにforドライラン(を使用echo)を実行する傾向があります。これらの場合mv、私はすでにいくつかの考えを入れているので、手で持つ必要はありません。
エイカット14年

7

上記の優れた回答に加えて、ファイルを移動するかどうかに関する質問が得られなかった理由を明確にしたいと思います。

1つのファイルを新しい名前に移動し、その名前がディレクトリではない場合、mvファイルの名前は新しい名前に変更されます。

ここでの問題は、実行に使用findしていたことですmvすべてのファイルに対して1回ではなく、ファイルごとに1です

代わりに、あなたが行ってしたい場合mv *90.mp3 90は、 mv「ターゲットファイルがディレクトリではありません」というエラーメッセージが表示されて失敗しただろう。

もう1つのアドバイスは、ターゲットパスを入力するときにタブ補完を使用することです。/ターゲット名に追加することにより、ターゲットがディレクトリかどうかを示します。またmv -i、既存のファイルを上書きするかどうかを尋ねられます。


代わりに、完了したmv *90.mp3 90場合、mvは「ターゲットファイルはディレクトリではありません」というエラーメッセージで失敗します。ええ、ええ、なぜそんなに複雑なのですか?私はあなたのラインを使用し、私は幸せになります。ただし、この些細な場合に限ります。:)これは私が質問をする通常の方法だからです。簡単にするために絞り込んでもらいます。findこれまでのところ、90年代のファイルが私が「キャッチ」したいさまざまなサブディレクトリに散らばっている可能性があることを考えると、誰も反対していません。それらが常に 1つのソースディレクトリにある場合にのみ、行が適用されます。mv
構文エラー14年

@syntaxerror非常に真実-これmvは、ツールの選択に対する批判としてではなく、動作の例として意味しました。
ジェニーD 14年

1
あなたは、ビルド組み合わせたものを、おそらく可能性findmv、例えばfind /music -type d -exec mv {}/*90.mp3 targetdir\;今、私は少し私はそれを過度に複雑、かつ簡単に使用しているように感じる- -iあるいは-t、より効率的である
ジェニーD

1
@Jenny:find . -type d -exec mv {}/*9?.mp3 target \;例がうまくいったとしても、ファイルが1つしか含まれていない各ディレクトリでmvコマンドが次のように見えるというリスクがあります。そのため、そのようなファイルはすべて(最後のファイルを除く)失われます。mv file target*9?.mp3
G-Manは「Reinstate Monica」と言います14

4
@syntaxerror:問題が発生した42,000行のスクリプト全体ではなく、問題の本質的な部分を公開する努力を称賛します。しかし、あなたはすべてに何かをしたかった場合でも*.mp3、あなたは、ディレクトリツリー内のファイルができshopt -s globstar、その後のあなたのコマンドを実行します**/*.mp3- **のように動作しますfind
Gマンは「Reinstate Monica」と言います14

1

別の汎用戦略として、この種の操作を一時的なスクリプトに変えることをお勧めします。私は実行の前に自分が何をしているかを確実に理解できるように、結果を見て手作業でコマンドにfind変換することを好みますmv。例えば。

find . -name '* 9?.mp3' > tmp
vim tmp

これで、ファイル名のリストを調べて、ファイルの内容をシェルコマンドとして書き換えることができます。

  • ファイルの内容を1行に入力します。 ggVGJ
  • 付加: Imv [esc]
  • 追加: Asomedir/ [esc]
  • ファイルを保存します。もう一度読んでください。呼吸する。
  • source tmpコマンドラインで実行します。

それは保守的な戦略ですが、タイプミス-execsedコマンド、またはシェル展開の誤解に頻繁にかまれており、ゆっくりとした一貫性のあるアプローチを取ることを好みます。

言い換えれば、私はuse病すぎて使用できません-exec


1
あなたは取り残され:%s/.*/"&"/、この場合には、あなたがことを知っている、ので-ステップを、すべてのファイル名は、少なくとも一つのスペースが含まれています。
G-Manが「Reinstate Monica」と言う14

1
ファイル名にスペースまたは他の特殊文字が含まれている場合、これは噛みつきます。適切に引用する必要があります。コマンドのリストを確認しても、エラーをキャッチする可能性は特に高くありません。コマンドを実行する前にレビューするより良い方法があります。たとえば、のecho mv代わりに実行し、満足であればmv削除しechoます。
ジル 'SO-悪であるのをやめる' 14年

ファイル名-と、スペースのようなミスをスポッティングすることは、この技術が:-)に役立ちますまさにです
トム・リース

0

別のオプション:

-n、-no-clobberは既存のファイルを上書きしません

-iと同じですが、尋ねることはなく、失敗します。

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