Batch renaming files in command line and Xargs

后端 未结 9 718
余生分开走
余生分开走 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:06

    My attempt from: https://www.tecmint.com/linux-image-conversion-tools/

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

    Using parallel

    parallel convert '{}' '{.}.jpg' ::: *.png
    
    0 讨论(0)
  • 2020-12-12 17:09

    This can be also be done with xargs and sed to change the file extension.

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

    You can print the original filename along with what you want the filename to be. Then have xargs use those two arguments in the move command. For the one-liner, I also added a grep to filter out anything not a *.png file.

    0 讨论(0)
  • 2020-12-12 17:11

    My solution is similar to many of the xarg solutions, and particularly similar to Schleis'.

    The difference here is a full regex manipulation with match references, and sed commands that properly ignore files that don't match so you don't need to prefilter your listing.

    This is also safe for files with spaces and shell meta.

    Change \2 in the replacement to any desired extension.

    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
    

    Explanation

    The -n arg tell's sed not to print anything by default, the T command says skip to the end of the script if the previous s command didn't do a replacement, the p command prints the pattern space (only hit if the s command matches).

    The & in the replacement is a reference to the contents of the original filename match.

    If we replace mv in the command with bash -c 'echo "run($#) $@"' bash then we can see the number of times mv would be called, and with parameter count and value:

    $ 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
    
    0 讨论(0)
  • 2020-12-12 17:11

    find ./xx -name "*.png" -print0 |sed 's/.png$//g'|xargs -0 -I% mv %.png %.jpg

    I like to use following command

    find ./xx -name "*.png" -type f|while read FILE; do
      mv "$FILE" "$(echo $FILE|sed -e 's/.png$/.jpg/')";
    done
    
    0 讨论(0)
  • 2020-12-12 17:15

    how do i rename the file so that I can just have one extension.

    cd dir/with/messedup/files
    
    for file in *.png.jpg; do
      mv "$file" "${file%.png.jpg}.jpg"
    done
    

    in the future, using xargs, how do I change the extension of the file simular to second command?

    To my knowledge, that can't be done. The best way to do it would be to use a for-loop with parameter substitution much like the one above:

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

    If you have files in subdirectories that you want converted, then you can pipe find to a while read loop:

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

    NOTE: It's generally considered a bad idea to use the output of ls in a shell script. While your example might have worked fine, there are lot's of examples where it doesn't. For instance, if your filenames happened to have newlines in them (which unix allows), ls probably won't escape those for you. (That actually depends on your implementation, which is another reason not to use ls in scripts; it's behavior varies greatly from one box to the next.) You'll get more consistent results if you either use find in a while-read loop or file globbing (e.g. *.png) in a for loop.

    0 讨论(0)
  • 2020-12-12 17:21

    Coming late to the party, but here's how you can rename files with xargs. Say you have a bunch of files named fileN.svg.png and you want to name them fileN.png where N could be a series of integers:

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

    The first xargs uses basename to strip off both .svg and .png to get a just filenameN. The second xargs receives that bare name and uses replacement to rename the file.

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