拡張子に$記号を含む.mp3ファイルがありますが、削除したいと思います。名前は次のとおりです。
1.mp3$$
2.mp3$$
etc.
彼らはそうしなければならない
1.mp3
etc.
頑張った
for f in *; do a="(echo $f | sed s/mp3$$/mp3/)"; mv "$f" "$a"; done
しかし、これはエラーメッセージを提供します
mv: rename 1.mp3$$ to (echo 1.mp3$$ | sed s/mp3582/mp3/): No such file or directory
各ファイルに。
それから答えを読んだ後これ質問、試してみました
for i in *mp3$$; do mv "$i" "mp3"; done
しかし、この方法は機能しなかっただけでなく、1つのファイルだけを残してすべて削除され、"mp3"というファイルだけが残りました。また、エラーメッセージも表示されます。
mv: rename *mp3582 to mp3: No such file or directory
幸いなことに、元のファイルはまだ残っていて名前を変更したいのですが、コマンドラインで "mp3$$"を "mp3"に変更するにはどうすればよいですか?
また、上記の2番目のコマンドで1つのファイルを除くすべてのファイルが削除されるのはなぜですか?
エラーメッセージにファイル名にない「3582」シーケンスが含まれているのはなぜですか?
PS:コマンドで$文字をエスケープするために$の代わりに\$を使用してみましたが、それも機能しません。
答え1
$$
すべてのPOSIX準拠シェルからシェルのプロセスIDに展開されます。
*.mp3$$
ファイルの変更は*.mp3
次のように行うことができます。
for i in *.mp3\$\$; do mv -i "$i" "${i%%\$\$}"; done
2番目のコマンドラインは明らかにPID 582を使用するシェルによって実行されるため、次のように拡張されます。
for i in *mp3582; do mv "$i" "mp3"; done
その後、ワイルドカード式に一致する項目がないため、ループは一度だけ実行され、ワイルドカード式をそのまま変数に配置します$i
。
mv "*mp3582" "mp3"
mv: rename *mp3582 to mp3: No such file or directory
2回目の試行では、各ファイルの名前を固定ファイル名「mp3」に変更し、「mp3」がすでに存在するディレクトリでない場合は、その名前で古いファイルを上書きします。エスケープ形式でも実行しようとすると、1つのファイルを除くすべてのファイルが削除される理由を説明できます。
for i in *mp3\$\$; do mv "$i" "mp3"; done
これを行うことができます:
mv <filename1>.mp3$$ mp3
mv <filename2>.mp3$$ mp3 # overwrites the previous "mp3"
mv <filename3>.mp3$$ mp3 # overwrites the previous "mp3" again
...
最初の試みは実際に修正可能です。
for f in *; do a="(echo $f | sed s/mp3$$/mp3/)"; mv "$f" "$a"; done # your version
for f in *; do a="$(echo \"$f\" | sed s/mp3\\$\\$/mp3/)"; mv "$f" "$a"; done # fixed version
括弧内のコマンドまたはパイプだけは実行されません。$( ... )
これには構成が必要です。スペース、セミコロン、またはその他のトリッキーな文字を含む可能性がある出力を処理するには、周囲に二重引用符を追加します。
その後、getの$文字が$( ... )
インタプリタを介して渡されます。二重:コマンドライン全体を解析するときは1回、$( ... )
実行のために構文を解析するときは一度。各パスからバックスラッシュエスケープ文字が削除されます。したがって、sedに対して "mp3 $ $"を維持するには、二重バックスラッシュが必要です。
また、ファイル名にスペースやその他のトリッキーな文字が含まれている場合は、$ fを二重引用符で囲む必要があり、二重引用符は別の二重引用符セット内にあり、渡すために保持しようとしているため、エスケープする必要があります$( ... )
。
答え2
あなたはこれを試すことができます
for file in *.mp3\$\$; do mv -v "$file" "${file/.mp3\$\$/.mp3}"; done
答え3
このperl
rename
ユーティリティを使用してください(完全に異なる互換性のないコマンドラインオプションを持つコマンドではrename
ありません)。util-linux
rename -n -v 's/\$+//g' *.mp3*
これは削除されますみんな $
の文字どこかにファイル名に。
$
ファイル名の末尾にある文字のみを削除するには、次のようにします。
rename -n -v 's/\$+$//' *.mp3*
ちなみに、上記のコマンドはrename
's オプションを練習の実行として使用し、実際に名前を変更することなく実行する作業を-n
示しています。rename
目的の操作が正確に行われ、意図しない結果が発生しないと確信している場合は、-n
コマンドラインから削除してください。削除-v
(詳細)オプションを選択することもできます。
perl
名前変更ユーティリティは、rename
Debian および派生ディストリビューション用のパッケージで使用できます。このパッケージには以下が含まれています。ファイル::名前の変更CPANモジュールとrename
ユーティリティ。
Debianでは、このパッケージの以前のバージョンにはperl
以前のバージョンが含まれていましたが、rename
いくつかの注目すべきバグがありました。このバージョンがインストールされている場合は、rename
できるだけ早くパッケージをインストールする必要があります。
このPerlベースの製品rename
は時々file-rename
またはprename
。 prename
通常、欠陥のある古いバージョンです。