你会这么善良并帮助我完成我的shell脚本。下面的脚本应找到源目录及其子目录中的所有图片,并将它们以较低的分辨率转换为目标目录,包括与源目录相同的子目录结构。我需要补充一点,我是shell脚本的初学者。
所有变量(例如FILELIST,DIRNAME,TFILENAME)似乎都列出了具有正确内容的变量。
我遇到的问题是,for循环只运行一次,因此变量DSTPATH(应具有正确的目标路径)仅在第一行中是正确的,并且影响变量TARGETFILE。
这对我来说很奇怪,因为我处于循环中。
#!/bin/sh
# must be with a /at the end
SRC=$1
DST=$2
FILELIST=`find $SRC -name '*.[Jj][Pp][Gg]'`
#for all files found
for SOURCEFILE in "$FILELIST"; do
# Get same subdirectory as in source
DIRNAME=`echo "$SOURCEFILE" | awk -F '[^/]*$' '{print $1}'`
SUBDIR=`echo "$DIRNAME" | awk -F "$SRC" '{ if ( NF > 1 ) print $NF }'`
# check if destination directory not exists, if so create it
# build destination directory name first
DSTPATH=${DST}"$SUBDIR"
if [ ! -d "$DSTPATH" ]
then
echo "$DSTPATH will be created"
# mkdir -p "$DSTPATH"
else
# normaly not needed
echo "$DSTPATH exists already"
fi
# build up target filename
TFILENAME=`echo "$SOURCEFILE" | awk -F '/' '{ if ( NF > 1 ) print $NF }'`
TBASENAME=`echo "$TFILENAME" | awk -F '.' '{$NF=""; sub("[.]$",""); print $1}'`
TEXT=`echo "$TFILENAME" | awk -F '.' '{print $NF}'`
TARGETFILE=`echo "$DSTPATH""$TBASENAME""_p1080.""$TEXT"`
# now the files can be converted with convert
# echo "Converting $SOURCEFILE to $TARGETFILE"
done
任何帮助都会非常令人难以置信。 提前致谢 谢伊尼
P.S。:我用'awk'做的所有字符串操作,无论出于何种原因我都没有找到,dirname和basename也不适用于我的脚本。
答案 0 :(得分:1)
变化:
for SOURCEFILE in "$FILELIST"; do
为:
for SOURCEFILE in $FILELIST; do
见:
A="one two three"
for I in "$A"; do echo $I; done
for I in $A; do echo $I; done
根据basename,dirname问题,这应该有效:
TFILENAME=$(basename "$SOURCEFILE")
答案 1 :(得分:0)
如果您需要使用包含空格的文件名,请尝试以下操作:
FILE_LIST="name with spaces.jpg
another one.txt
one more.txt"
echo $FILE_LIST | while read LINE
do
echo "Filename is [$LINE]"
done
注意,在此代码中,循环在子进程中运行(而在“|”之后)。 您可以从外部作用域访问(副本)每个全局变量,但更改它们(循环中的副本)将不会影响外部作用域(在“完成”之后)。
答案 2 :(得分:0)
非常感谢,
现在它可以工作,我可以开始调整我的图像大小
请参阅下面的脚本我目前如何使用它。接下来的步骤将是优化性能和逻辑,因为此脚本在我的NAS上运行(低CPU和内存性能,QNAP TS-219P)
#!/bin/sh
# must be with a /at the end
SRC=$1
DST=$2
# switch to working directory, for imagemagicks temp-path (will be changed later)
cd /share/Show_pictures/
# Temporary path used by imagemagick to convert images (dos not work so far)
TMP_PATH=`echo "/share/share/Network Recycle Bin 1"`
# Get File list of source directory for converting
FILELIST=`find $SRC -name '*.[Jj][Pp][Gg]'`
echo "$FILELIST" > ./filelist
# for all files found
echo "$FILELIST" | while read LINE
do
# Get same subdirectory as in source
DIRNAME=`echo "$LINE" | /opt/bin/awk -F '[^/]*$' '{print $1}'`
SUBDIR=`echo "$DIRNAME" | /opt/bin/awk -F "$SRC" '{ if ( NF > 1 ) print $NF; else print "nothing" }'`
# check if destination directory not exists, if so create it
# build destination directory name first
DSTPATH="$DST""$SUBDIR"
if [ ! -d "$DSTPATH" ]
then
echo "$DSTPATH will be created"
mkdir -p "$DSTPATH"
# else
# normaly not needed
# echo "$DSTPATH exists already"
fi
# build up target filename
TFILENAME=`echo "$LINE" | /opt/bin/awk -F '/' '{ if ( NF > 1 ) print $NF; else print "nothing" }'`
TBASENAME=`echo "$TFILENAME" | /opt/bin/awk -F '.' '{$NF=""; sub("[.]$",""); print $1}'`
TEXT=`echo "$TFILENAME" | /opt/bin/awk -F '.' '{print $NF}'`
TARGETFILE=`echo "$DSTPATH""$TBASENAME""_p1080.""$TEXT"`
# now the files can be converted with convert
# but only it target file does not exist already (later check with difference by iamgemagick)
if [ ! -f "$TARGETFILE" ]
then
echo "Converting $LINE to $TARGETFILE"
# convert usage of imagemagick
/opt/bin/convert -define registry:temporary-path="$TMP_PATH" -define jpeg:size=5200x5200 "$LINE" -auto-orient -resize '>1920x1080' "$TARGETFILE"
else
echo "$TARGETFILE exists already"
fi
done