开发者

Filter Hidden Files with Bash (for Batch Image Resize Script)

I'm writing a script to batch resize images. Originally I was applying an operation for file in $(ls $1), but I would like to be able to use globbing, so I'm looking at something more like for file in $(echo $1). The problem is that dotglob may or may not be enabled, so echo * could return hidden files (notably, .DS_Store), which cause convert to throw an error and stop the script. I would like the default behavior of the command to be that if I cd into a directory full of images and execute resize * 400x400 jpg, all of the images will be resized excluding hidden files, regardless of whether dotglob is enabled.

So, in pseudo code, I'm looking for:

for file in $(echo $1 | [filter-hidden-files])

Here is my script with the older behavior. Will update with new behavior when I find a solution:

# !/bin/bash

# resize [folder] [sizeXxsizeY] [outputformat]
# if [outputformat] is omitted, the input file format is assumed

for file in $(ls $1)
do
    IMGNAME=$(echo "$file" | cut -d'.' -f1)
    if test -z $3
    then
        EXTENSION=$(echo "$file" | cut -d'.' -f2)
        convert $1/$file -resize $2 -quality 100 $1/$IMGNAME-$2.$EXTENSION
        echo "$file => $IMGNAME-$2.$EXTENSION"
    else 
        convert $1/$file -resize $2 -quality 100 $1/$IMGNAME-$2.$3
        echo "$file => $IMGNAME-$2.$3"
    fi
done

Here is the current script:

# !/bin/bash

# resize [pattern] [sizeXxsizeY] [outputformat]
# if [outputformat] 开发者_JS百科is omitted, the input file format is assumed

for file in $(echo $1)
do
        IMGNAME=$(echo "$file" | cut -d'.' -f1)
        if test -z $3 && if test -f $3
        then
            EXTENSION=$(echo "$file" | cut -d'.' -f2)
            convert $file -resize $2 -quality 100 $IMGNAME-$2.$EXTENSION
            echo "$file => $IMGNAME-$2.$EXTENSION"
        else 
            convert $file -resize $2 -quality 100 $IMGNAME-$2.$3
            echo "$file => $IMGNAME-$2.$3"
        fi
done

Given the command resize * 400x400, convert throws an error as it cannot process .DS_Store (a hidden file residing in every file on an OSX system). As I will never be processing hidden images, I would like to automatically filter them. I've been trying to do this with grep or find, but I haven't figured it out yet.

New script goes here:

for file in $(echo $1)
do


I would suggest changing the commandline of your script from resize * 400x400 to resize 400x400 *, the script would be more like the standard unix tools that way (grep, sed, ln, etc.). You would not have to unset the dotglob option in your script (which is better since it's up to the user of the script if he wants hidden files globbed or not).

Your script would look something like this:

#!/bin/bash

OUTPUTFORMAT=$1
# Remove original $1 from the list of arguments
shift

for i in "$@"
do
    # Use $OUTPUTFORMAT here
    etc....

If you do not want to change the commandline for your script. You could try setting GLOBIGNORE

export GLOBIGNORE=".*"

Or if extglob is set you could try file globbing like so:

echo !(.*)


There is a dotglob shell option that decides if files starting with . are included when globbing. You can check if this is the case with

shopt dotglob

You also can explicitly disable it in your script:

#!/bin/bash

shopt -u dotglob

for file in $1/*; do
  ...
done


there's no need to use ls with a for loop, most of the time its useless. also the for loop with * doesn't return hidden files, unless you specifically specify it. To show hidden files,

for files in .*
do
 echo $files
done


as you are getting a list of files in $* you can check them one by one

for i in $*
do 
   expr $i : '^\..*' > /dev/null && continue
   # process file
done
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜