Batch renaming files in command line and Xargs

后端 未结 9 719
余生分开走
余生分开走 2020-12-12 16:32

So, I have the following structure:

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

I ran a command to resize them

ls | xargs -I xx convert xx -res         


        
相关标签:
9条回答
  • 2020-12-12 17:21

    I'm late to this party by about 3 years, I just had a similar problem which I figured out myself. I had a list of png files which I converted using inkscape, because ImageMagick's svg support is poor.

    I originally converted them by doing:

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

    Which of course led to the same issue like posted above.

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

    I wanted to rename *.svg.png to *.png, this is what I wound up with...

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

    This does three things:

    1. find in this directory files named *.svg.png, the -print0 prints to standard output
    2. sed modifies the standard output, basically swap .svg.png with nothing, so I'd get: file1/file2/file3/file4
    3. xargs -0 to get the data from sed, -I references the filename w/o the extension, then mv original filename to new filename. The word namePrefix isn't anything special, just wanted to make it clear.

    EDIT

    I realize now this is the most convoluted way to do this. One can simply use the rename command.

    rename 's/svg\.png/.png/' *
    
    0 讨论(0)
  • 2020-12-12 17:22

    After some investigation on similar task here is my code:

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

    Reasoning:

    • renaming will not compress the file (so use convert instead of mv)
    • ls \.png$ | xargs will not deal with spaces in the path/filename
    • find . will search in sub-folders, so use -maxdepth 1
    • convert doesn't use available CPUs so -P8 (or -P other)
    • sed without 'g' at the end will not substitute all files (only one)
    • sed 's/.png//g' will leave no extension (basename could also work but didn't after -print0)
    • parallel - potentially better solution but didn't work on my Ubuntu 18.04 bash 4.4
    • % is the smallest common symbol for substitution (compare to {} xx namePrefix)
    • -n2 parameter is good for xargs but didn't work with -print0 properly (n number of entries to take and pass after xargs)
    • -quality 100 default magic quality is 92 (which is fine), here 100% to avoid loosing anything
    0 讨论(0)
  • 2020-12-12 17:23

    To clean up your error, try the rename utility. Check the manpage for details.

    In your case, you'd do rename '.png.jpg' '.jpg' ./* if your current directory is set appropriately.

    Since you have convert available, I'm assuming you have mogrify too (imagemagick suite). Whenever I want to do this, I copy the files into a different directory and use mogrify instead. I usually need this only for resizing, but if you change the image format aswell, mogrify will handle the filenames (make new files with proper filenames).

    You would use it as mogrify -format jpg -resize [size] ./*.png. I'm not sure what -resize without geometry arguments is supposed to do. It isn't documented and doesn't work on my machine.

    As Tim Pote reasoned, I don't think you can make xargs handle filenames and extensions separately.

    0 讨论(0)
提交回复
热议问题