为什么同步图像的 for 循环只运行一次?

发布于 2024-11-01 16:26:22 字数 1466 浏览 1 评论 0原文

下面的脚本将从源目录及其子目录中查找所有图片,并将其以较低的分辨率转换到目标目录中,包括与源目录相同的子目录结构。

所有变量(例如FILELISTDIRNAMETFILENAME)似乎都列出了具有正确内容的变量。

我遇到的问题是 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

我使用 awk 执行所有字符串操作,无论出于何种原因 dirnamebasename 也不适用于我的脚本。

Below script shall find all pictures from the source directory and its sub-directories and convert them with a lower resolution into the target directory, including the same sub-directory structure as the source directory.

All variables (like FILELIST, DIRNAME, TFILENAME) seem to list variables with the correct content.

The problem I have is that the for loop runs only once, therefore the variable DSTPATH (which shall have the correct destination path) only is correct in the first line and impacts as well the variable TARGETFILE.

This looks strange to me, as I'm in a loop.

#!/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 '[^/]*

I do all string operations with awk, as for whatever reason dirname and basename do not work with my script either.

'{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("[.]
quot;,""); 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

I do all string operations with awk, as for whatever reason dirname and basename do not work with my script either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌若浮生 2024-11-08 16:26:22

更改:

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")

Change:

for SOURCEFILE in "$FILELIST"; do 

to:

for SOURCEFILE in $FILELIST; do 

See this:

A="one two three"
for I in "$A"; do echo $I; done
for I in $A; do echo $I; done

according to basename, dirname issue, this should work:

TFILENAME=$(basename "$SOURCEFILE")
情愿 2024-11-08 16:26:22

如果您需要使用带空格的文件名,请尝试以下操作:

FILE_LIST="name with spaces.jpg
another one.txt
one more.txt"
echo $FILE_LIST | while read LINE
do 
    echo "Filename is [$LINE]"
done

请注意,在此代码中,循环在子进程中运行(while 在“|”之后)。
您可以从外部作用域访问每个全局变量(的副本),但更改它们(循环中的副本)将不会对外部作用域产生任何影响(在“完成”之后)。

If you need to work with filenames with spaces, try this:

FILE_LIST="name with spaces.jpg
another one.txt
one more.txt"
echo $FILE_LIST | while read LINE
do 
    echo "Filename is [$LINE]"
done

Note, that in this code, the loop is running in a subprocess (while is after "|").
You have access to (copy of) each global variable from outer scope, but changing them (copies in a loop) will have no effect in outer scope (after "done").

故事和酒 2024-11-08 16:26:22

非常感谢,

现在它可以工作了,我可以开始调整图像大小,

请参阅下面的脚本,我目前如何使用它。下一步将是优化性能和逻辑,因为此脚本在我的 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

Thanks a lot,

now it works and I can start resizing my images

See below the script how I use it for the moment. The next steps will be to optimize performance and logic, as this script runs on my NAS (low CPU and Memory performance, 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文