Use output from awk as input for mv

5,717

Solution 1

Incorporate mv into awk using the system() function:

awk '$1<500 && $2<500 {system("mv "$3" /destination")}

Change the mv command to meet your need, here i have used:

mv /file_(third_field)_from_awk /destination

Also you don't need multiple awks, only one would suffice as shown above.

Solution 2

With the assumption that you are not having filenames with embedded newlines, you can use the GNU mv and xargs programs to do this.

 ... | awk ... | xargs -d'\n' mv -t ./small_images

xargs collects the filenames from the input and appends them onto the mv -t ./small_images command, splitting very long commands as needed. You need a version of mv that has the -t option to specify the destination directory at the start of the command, or else write a tiny script to handle it.

Share:
5,717

Related videos on Youtube

cjm
Author by

cjm

Updated on September 18, 2022

Comments

  • cjm
    cjm almost 2 years

    I'm trying to write a script (or a one-liner) that finds all image files with small dimensions and then moves them into a directory. Based on this answer from Ask Ubuntu, I was able to generate a list of files with both dimensions lower than 500, and then I was able to find all common images files as well as .jpg.

    find -E . -regex ".*\.(jpg|gif|png|jpeg)" -type f -exec identify -format '%w %h %i\n' '{}' \; | awk '$1<500 && $2<500' | awk '{print $3}'
    

    The second awk is so that it only prints the file name, which I was hoping to use in the input to mv. How can I get that output into mv?


    Sample output of the first awk is:

    123 456 ./smallimage.jpg
    333 333 ./square.png
    

    The second awk just gives out

    ./smallimage.jpg
    ./square.png
    

    However, I can't seem to find a way to get this list of filenames as the input for an mv command, as the desired resulting final command is some form of mv <file list> ./small_images/

  • cjm
    cjm over 7 years
    That worked! Thanks for the fast answer; turning $3 into substr($3,3) (and testing by turning system to print) gave almost exactly the result I wanted. The only other thing I'd want to do is make the regex ignore subdirectories and case-insensitive to the file extension.
  • cjm
    cjm over 7 years
    How would that handle files in subdirectories or those already moved?
  • cjm
    cjm over 7 years
    My final one-liner ended up as find -E . -iregex ".*\.(jpg|gif|png|jpeg|bmp)" -type f -exec identify -format '%w %h %i\n' '{}' \; | awk '$1<500 && $2<500 {system("mv "substr($3,3)" small_images/"substr($3,3)"")}'. You could add more image formats if you really wanted to, but I'm pretty sure I don't have any tga or tiff files that I'm interested in.