web-dev-qa-db-ja.com

コマンドラインおよびXargsでのファイル名の一括変更

だから、私は次の構造を持っています:

.
..
a.png
b.png 
c.png

サイズを変更するコマンドを実行しました

ls | xargs -I xx convert xx -resize xx.jpg

今私のディレクトリはこのようになります

.
..
a.png.jpg
a.png
b.png.jpg
b.png
c.png.jpg
c.png

最初の質問は、ファイルの名前を変更して拡張子を1つだけにする方法です。 2つではありません。 (基本的に、元のミスをどのようにクリーンアップしますか?)

2つ目の質問は、将来、xargsを使用して、ファイルの拡張子を2番目のコマンドに似せて変更するにはどうすればよいですか?

27
Cripto

ファイルの名前を変更して、拡張子を1つだけにする方法.

cd dir/with/messedup/files

for file in *.png.jpg; do
  mv "$file" "${file%.png.jpg}.jpg"
done

将来、xargsを使用して、ファイルの拡張子を2番目のコマンドに変更するにはどうすればよいですか?

私の知る限り、それはできません。これを行うための最良の方法は、上記のようなパラメータ置換を伴うforループを使用することです。

for file in *.png; do
  convert "$file" -resize "${file%.png}.jpg"
done

変換したいサブディレクトリにファイルがある場合は、findwhile readループにパイプできます。

find . -type f -name '*.png' |
while read file; do
  convert "$file" -resize "${file%.png}.jpg"
done

注:一般に 悪い考え と見なされ、シェルスクリプトのls。あなたの例はうまくいったかもしれませんが、うまくいかない例がたくさんあります。たとえば、ファイル名に改行が含まれている場合(UNIXではこれが許可されています)、lsはおそらくそれらをエスケープしません。 (これは実際には実装に依存します。これはスクリプトでlsを使用しないもう1つの理由です。その動作はボックスごとに大きく異なります。)findは、while-readループで、またはファイルグロビング(たとえば、*.png)はforループで。

20
Tim Pote

これは、xargsおよびsedを使用してファイル拡張子を変更することもできます。

ls | grep \.png$ | sed 'p;s/\.png/\.jpg/' | xargs -n2 mv

元のファイル名と、希望するファイル名を印刷できます。次に、xargsにmoveコマンドでこれらの2つの引数を使用させます。ワンライナーの場合は、*。pngファイル以外のものを除外するgrepも追加しました。

51
Schleis

パーティーには遅れますが、xargsを使用してファイルの名前を変更する方法は次のとおりです。 fileN.svg.pngという名前の一連のファイルがあり、それらにfileN.pngという名前を付けたいとします。ここで、Nは一連の整数です。

ls *.svg.png | xargs basename -s .svg.png | xargs -I {} mv {}.svg.png {}.png

最初のxargsはbasenameを使用して両方の.svg and .pngを取り除き、_filenameNだけを取得します。 2番目のxargsはその裸の名前を受け取り、置換を使用してファイルの名前を変更します。

11
Dethe

エラーをクリーンアップするには、renameユーティリティを試してください。詳細については、マンページを確認してください。

あなたの場合、現在のディレクトリが適切に設定されていれば、rename '.png.jpg' '.jpg' ./*を実行できます。

利用可能なconvertがあるので、mogrifyimagemagick suite)もあると思います。これを行う場合はいつでも、ファイルを別のディレクトリにコピーし、代わりにmogrifyを使用します。通常、これはサイズ変更にのみ必要ですが、画像形式も変更すると、mogrifyがファイル名を処理します(適切なファイル名で新しいファイルを作成します)。

mogrify -format jpg -resize [size] ./*.pngとして使用します。ジオメトリ引数なしで-resizeが何をすることになっているかわからない。それは文書化されておらず、私のマシンでは動作しません。

Tim Poteが推論したように、xargsにファイル名と拡張子を個別に処理させることはできないと思います。

6
Matej

私はこのパーティーに約3年遅れており、私が自分で考え出した同様の問題を抱えていました。 ImageMagickのsvgサポートが貧弱なため、inkscapeを使用して変換したpngファイルのリストがありました。

私は最初にそれらを変換して変換しました:

find . -name "*.svg" -exec inkscape {} --export-png={}.png

もちろん、どちらが上記のように同じ問題を引き起こしました。

file1.svg
file1.svg.png
file2.svg
file2.svg.png
file3.svg
file3.svg.png
file4.svg
file4.svg.png

* .svg.pngの名前を* .pngに変更したかったのですが、これは私が巻き込んだものです...

find . -name "*.svg.png" -print0 | sed 's/.svg.png//g' | xargs -0 -I namePrefix mv namePrefix.svg.png namePrefix.png

これは次の3つのことを行います。

  1. このディレクトリで* .svg.pngという名前のファイルを見つけ、-print0は標準出力に出力します
  2. sedは標準出力を変更します。基本的には.svg.pngを何も入れ替えないので、file1/file2/file3/file4を取得します。
  3. xargs -0はsedからデータを取得し、-Iは拡張子なしのファイル名を参照し、次にmv元のファイル名を新しいファイル名に参照します。 WordのnamePrefixは特別なものではなく、明確にしたいだけです。

[〜#〜]編集[〜#〜]

今、これが最も複雑な方法です。 renameコマンドを使用するだけです。

rename 's/svg\.png/.png/' *
5
Paul J

同様のタスクのいくつかの調査の後、ここに私のコードがあります:

find . -maxdepth 1 -name '*.png' -print0 | sed 's/.png//g' | xargs -0 -I% -n 1 -P 8 convert -quality 100 %.png %.jpg

推論:

  • 名前を変更してもファイルは圧縮されません(したがって、convertの代わりにmvを使用してください)
  • ls \.png$ | xargsはパス/ファイル名のスペースを扱いません
  • find .はサブフォルダ内を検索するため、-maxdepth 1を使用します
  • convertは使用可能なCPUを使用しないため、-P8(または-P other
  • sedなしで'g'を最後に付けないと、すべてのファイルが置き換えられません(1つだけ)
  • sed 's/.png//g'は拡張子を残しません(basenameも機能しましたが、-print0以降は機能しませんでした)
  • parallel-潜在的に優れたソリューションですが、Ubuntu 18.04 bash 4.4では機能しませんでした
  • %は、置換の最小共通シンボルです({} xx namePrefixと比較してください)
  • -n2パラメータはxargsには適していますが、-print0では適切に機能しませんでした(nxargsの後に取得して渡すエントリ数)
  • -quality 100デフォルトの魔法の品質は92(これは問題ありません)で、何も失われないようにここでは100%です。
3
Alexey K.

私のソリューションは多くのxargソリューションに似ており、特にSchleis 'に似ています。

ここでの違いは、一致参照による完全な正規表現操作と、一致しないファイルを適切に無視するsedコマンドであるため、リストを事前にフィルターする必要はありません。

これは、スペースとシェルメタを含むファイルに対しても安全です。

置換の_\2_を任意の拡張子に変更します。

_ls |
sed -nE 's/Rick\.and\.Morty\.(S03E[0-9]{2})\..*(\.[a-z0-9]{3})/"&" "Rick and Morty \1\2"/;T;p' |
xargs -n 2 mv
_

説明

_-n_ argはデフォルトでは何も印刷しないように指示します。Tコマンドは、前のsコマンドが置き換えを行わなかった場合、スクリプトの最後にスキップするように指示します。 pコマンドはパターンスペースを出力します(sコマンドが一致する場合のみヒットします)。

置換の_&_は、元のファイル名の一致の内容への参照です。

コマンドのmvbash -c 'echo "run($#) $@"' bashに置き換えると、mvが呼び出される回数と、パラメーターのカウントと値を確認できます。

_$ ls |
  sed -nE 's/Rick\.and\.Morty\.(S03E[0-9]{2})\..*(\.[a-z0-9]{3})/"&" "Rick and Morty \1\2"/;T;p' |
  xargs -n 2 bash -c 'echo "run($#) $@"' bash
run(2) Rick.and.Morty.S03E02.720p.HDTV.x264-BATV.mkv Rick and Morty S03E02.mkv
run(2) Rick.and.Morty.S03E03.720p.HDTV.x264-BATV.mkv Rick and Morty S03E03.mkv
run(2) Rick.and.Morty.S03E04.720p.HDTV.x264-BATV.mkv Rick and Morty S03E04.mkv
run(2) Rick.and.Morty.S03E05.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E05.mkv
run(2) Rick.and.Morty.S03E06.720p.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E06.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E07.720p.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E07.mkv
run(2) Rick.and.Morty.S03E08.720p.HDTV.x264-BATV.mkv Rick and Morty S03E08.mkv
run(2) Rick.and.Morty.S03E09.720p.HDTV.x264-BATV.mkv Rick and Morty S03E09.mkv
run(2) Rick.and.Morty.S03E10.720p.HDTV.x264-BATV.mkv Rick and Morty S03E10.mkv
_
1
joshperry

私の試み: https://www.tecmint.com/linux-image-conversion-tools/

ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.png}.jpg"'

パラレルを使用する

parallel convert '{}' '{.}.jpg' ::: *.png
0
SergioAraujo