用于同步图像的Shell脚本仅在for循环中运行一次

时间:2011-04-15 19:53:55

标签: shell variables for-loop

你会这么善良并帮助我完成我的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也不适用于我的脚本。

3 个答案:

答案 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