我正在编写一个脚本来批量调整图像大小。最初我正在应用一个操作for file in $(ls $1)
,但我希望能够使用globbing,所以我正在寻找更像for file in $(echo $1)
的东西。问题是dotglob可能启用也可能不启用,因此echo *
可以返回隐藏文件(特别是.DS_Store),这会导致convert
抛出错误并停止脚本。 我希望命令的默认行为如果我cd
进入一个充满图像的目录并执行resize * 400x400 jpg
,那么所有图像都将被调整大小排除隐藏文件,无论是否启用了dotglob。
所以,在伪代码中,我正在寻找:
for file in $(echo $1 | [filter-hidden-files])
这是我的旧行为的脚本。当我找到解决方案时,将使用新行为进行更新:
# !/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
以下是当前脚本:
# !/bin/bash
# resize [pattern] [sizeXxsizeY] [outputformat]
# if [outputformat] 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
给定命令resize * 400x400
,convert会抛出错误,因为它无法处理.DS_Store(驻留在OSX系统上每个文件中的隐藏文件)。由于我永远不会处理隐藏的图像,我想自动过滤它们。我一直试图用grep或者找到这个,但我还没想到它。
新脚本在这里:
for file in $(echo $1)
do
答案 0 :(得分:3)
我建议将脚本的命令行从resize * 400x400
更改为resize 400x400 *
,该脚本更像是标准的unix工具(grep
,sed
, ln
等)。您不必在脚本中取消设置dotglob选项(这是更好的,因为如果他想要隐藏文件全局或不通过,则由脚本的用户决定。)
你的脚本看起来像这样:
#!/bin/bash
OUTPUTFORMAT=$1
# Remove original $1 from the list of arguments
shift
for i in "$@"
do
# Use $OUTPUTFORMAT here
etc....
如果您不想更改脚本的命令行。您可以尝试设置GLOBIGNORE
export GLOBIGNORE=".*"
或者,如果设置了extglob
,您可以像这样尝试文件通配:
echo !(.*)
答案 1 :(得分:1)
有一个dotglob
shell选项,用于决定在globbing时是否包含以.
开头的文件。您可以使用
shopt dotglob
您也可以在脚本中明确禁用它:
#!/bin/bash
shopt -u dotglob
for file in $1/*; do
...
done
答案 2 :(得分:1)
当您获得$ *中的文件列表时,您可以逐个检查它们
for i in $*
do
expr $i : '^\..*' > /dev/null && continue
# process file
done
答案 3 :(得分:1)
没有必要使用带有for循环的ls,大多数时候它没用。除非您特别指定,否则带有*的for循环不会返回隐藏文件。要显示隐藏文件,
for files in .*
do
echo $files
done