質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
terminal

Terminalは、Apple社のmacOSに標準で付属しているUNIX端末エミュレータ。UNIXコマンドによってMacの操作および設定を行うことができます。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Q&A

解決済

3回答

1198閲覧

xargsからmvコマンドへの入力について

narish

総合スコア14

terminal

Terminalは、Apple社のmacOSに標準で付属しているUNIX端末エミュレータ。UNIXコマンドによってMacの操作および設定を行うことができます。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

0グッド

0クリップ

投稿2018/09/30 13:11

編集2018/10/01 03:15

前提・実現したいこと

macOSでターミナル(UNIX)を使っています
複数ファイルの一括リネームがしたくてgoogle先生に教わりながらこのコマンドにたどり着いたのですが、以下のエラーが出ます
mvコマンドの入力がないという警告だと思うのですが、解決法がわからず…

find [Directory] -type f | sed 's/A/B/pg' | xargs mv -i

発生している問題・エラーメッセージ

usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory

試したこと

google先生に頼りました
初心者すぎてすみません

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

たとえばこのようなshell script (./hoge.sh) を作成して、

bash

1#!/bin/bash 2 3source=$1 4target=$(echo $source | sed -e 's/年/-/g' -e 's/月/-/g' -e 's/日//g' -e 's/ //g' -e 's/ //g) 5if [[ ${target} -ne ${source} ]]; then 6 mv ${source} ${target} 7fi

こうすればどうですか?

bash

1find [Directory] -type f -exec ./hoge.sh {} \;

ただし、フォルダに 年、月などがはいっていないことが条件ですけれども。

投稿2018/10/01 14:14

fu7mu4

総合スコア1088

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

narish

2018/10/03 03:51

回答ありがとうございました シンプルに解決できる方をベストアンサーに選びました 今後もよろしくお願いします
guest

0

ベストアンサー

mv 元のファイル名 新しいファイル名です。

Bash

1find [Directory] -type f | while read file; do mv -i </dev/tty $file ${file//A/B};done

ディレクトリ以下の全てのファイルについて、リネームしてしまいますが、大丈夫でしょうか?
まずは、

Bash

1find [Directory] -type f | while read file; do echo mv -i $file ${file//A/B};done

のようにechoで確認してください。

また、「ファイル名中の全てのABに変える」のでなく、「ファイル名中の最初のABに変える」でいいなら、renameコマンドが使えます。-n 1 -pは1ファイルずつ確認するためのオプションです。

Bash

1find [Directory] -type f | xargs -n 1 -p rename A B

#追記

"yyyy年mm月dd日"という書式でネーミングされているものを"yyyy-mm-dd"に変えたいのです。
そして、"yyyy年mm月dd日あああ"のような無駄な文字列をまとめて削除すべく、先頭から10文字以外を削除するコマンドがあればそれも付け加えたいです。

Bash

1find [Directory] -type f | while read f;do mv -i </dev/tty $f ${f:0:4}-${f:5:2}-${f:8:2};done

#訂正
追記のスクリプトは間違っています。コメント参照。コメントに書いたことで解決したようですが、こちらも訂正しておきます。

Bash

1find [Directory] -type f | while read file 2do 3 dir=${file%/*} 4 name=${file##*/} 5 mv -i </dev/tty "$file" "$dir/${name:0:4}-${name:5:2}-${name:8:2}" 6done

投稿2018/09/30 14:59

編集2018/10/02 12:17
otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

narish

2018/10/01 13:41

回答ありがとうございます。 echoで確認したところ欲しい結果が出ています。 ディレクトリ内のすべてのファイルに適用したいので問題ありません。 また、ファイル名中のすべての対象を処理したいのでrenameコマンドではダメなのですが、そもそもmacOSのUNIXにはrenameコマンドは存在しないようです… 複数のリネーム条件を並列するにはどうすればいいですか? それとリネーム後のファイル名を先頭から指定文字数だけ残して削除する方法はありますでしょうか?
otn

2018/10/01 13:54

おっと、renameはLinux独自でしたか。失礼しました。 > 複数のリネーム条件を並列するにはどうすればいいですか? これはどういう意味ですか? > それとリネーム後のファイル名を先頭から指定文字数だけ残して削除する方法はありますでしょうか? は、abcde を abc にリネームするというようなことでしょうか?先頭(0文字目)から3文字だとすると、 find [Directory] -type f | while read file; do mv -i $file ${file:0:3};done
otn

2018/10/01 13:56

あ、別の方へのコメントで分かりました。回答に追記しておきます。
doda

2018/10/01 15:31

> find [Directory] -type f | while read file; do mv -i $file ${file//A/B};done これだとmvで上書きが発生する時に、プロンプトに対する応答をfindの結果から読もうとして期待していない動作をしませんか? 手元のFreeBSDだと find [Directory] -type f | while read file; do mv -i $file ${file//A/B} < /dev/tty;done ならば大丈夫そうです。
otn

2018/10/01 15:35

おお、そうですね。 mv -i とかしたこと無いので、気づきませんでした。 ありがとうございます。訂正しておきます。
narish

2018/10/02 02:14

> find [Directory] -type f | while read f;do mv -i </dev/tty $f ${f:0:4}-${f:5:2}-${f:8:2};done なるほど、指定の書式に添わせる方法があるんですね。 これがシンプルでいいと思いやってみたところ、どうも絶対パスの行頭からカウントしてしまうようです。 一応対象のフォルダをcdに指定はしているんですが、どうすればいいでしょうか?
otn

2018/10/02 04:18

失礼しました。駄目ですね。 Bashのバージョンが新しければ、末尾から何文字目と指定する事も出来ますが、末尾に文字がくっつくケースもあるようでこれも駄目ですね。 やり方としては、$f をディレクトリとファイル名に分離して処理する事になります。 1つのディレクトリの中だけ見ればいいのであれば、 cd ~~ for f in *年*月*日*;do mv -i $f ${f:0:4}-${f:5:2}-${f:8:2};done で。
narish

2018/10/02 12:37 編集

繰り返し修正いただき、ありがとうございます。 概ね希望通りになりました。 これで"日"以降の末尾の文字列に空白を含む場合にも使えるといいのですが、簡単にできるのでしょうか?
otn

2018/10/02 12:10

空白が含まれる場合は、" " で囲んでください。 for f in *年*月*日*;do mv -i "$f" ${f:0:4}-${f:5:2}-${f:8:2};done
narish

2018/10/02 12:37

追記 実行したファイルの拡張子が消えていることに気がつきました。 拡張子も残したいです。
otn

2018/10/02 13:09

${f:0:4}-${f:5:2}-${f:8:2}.${f%%*.} ですかね。
narish

2018/10/02 13:39

for f in *年*月*日*;do mv -i "$f" ${f:0:4}-${f:5:2}-${f:8:2}.${f%%*.};done 以上を実行したところ、 0000年00月00日.txt これが以下のようになりました 0000-00-00.0000年00月00日.txt それと、空白を含むファイルはうまくいきませんでした これだと空白は問題なかったのですが… for f in *年*月*日*;do mv -i "$f" ${f:0:4}-${f:5:2}-${f:8:2};done お手数おかけします(^^;;
otn

2018/10/02 14:09

すいません。記号の間違いでした。 ${f##*.} です。 なんか間違い多くてすいませんね。
narish

2018/10/03 03:49

for f in *年*月*日*;do mv -i "$f" ${f:0:4}-${f:5:2}-${f:8:2}.${f##*.};done これでうまくいきました!! なんども修正していただきありがとうございました(^_^)
guest

0

find [Directory] -type f | sed 's/A/B/pg'

この部分だけ実行すると、ディレクトリ以下のファイルで名前が Aを Bに変換したもののリストがでると思います。mv コマンドで名前を変換するには、変換前と変換後の2つが必要ですので適切ではないと思います。

ググルとこのような情報がありましたので参考にしてください。
http://uguisu.skr.jp/Windows/find_xargs2.html

またはどのように変更したいのかを具体的に説明してください。

投稿2018/09/30 14:23

fu7mu4

総合スコア1088

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

narish

2018/10/01 13:32

具体的に言いますと、ディレクトリ内の複数のファイルが"yyyy年mm月dd日"という書式でネーミングされているものを"yyyy-mm-dd"に変えたいのです。 その際、半角・全角のスペースを含む場合は削除して間を詰める処理もかけたいので sed -e 's/年/-/pg' -e 's/月/-/pg' -e 's/ //pg' -e 's/ //pg' こんな感じでコマンドを並列しようかと考えました。 xargsを除いて実行すると欲しい結果がリストで出るのですが、それをファイルに適用する方法がわかりません。 そして、"yyyy年mm月dd日あああ"のような無駄な文字列をまとめて削除すべく、先頭から10文字以外を削除するコマンドがあればそれも付け加えたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問