Shell脚本:找不到引号中的文件夹

时间:2017-09-21 12:00:47

标签: bash shell

我遇到以下shell脚本的问题:

#!/bin/bash

searchPattern=".*\/.*\.abc|.*\/.*\.xyz|.*\/.*\.[0-9]{3}"
subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0 | sed 's/.*/"&"/')

echo "subFolders: $subFolders"

# iterate through subfolders
for thisFolder in $subFolders
do
  echo "The current subfolder is: $thisFolder"

  find -E $thisFolder -type f -iregex $searchPattern -maxdepth 1 -print0 | xargs -0 7z a -mx=9 -uz1 -x!.DS_Store ${thisFolder}/${thisFolder}_data.7z
done

它背后的想法是在每个子文件夹的一个7z存档中存档带有.abc,.xyz和.000-.999结尾的文件类型。但是,我无法处理包括空格在内的文件夹。当我运行如上所示的脚本时,我总是收到以下错误:

find: "20130117_test": No such file or directory

如果我使用行

运行脚本
subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0 | sed 's/.*/"&"/')

更改为

subFolders=$(find -E * -type d -regex ".*201[0-4][0-1][0-9].*|.*20150[1-6].*" -maxdepth 0)

脚本的工作方式与魅力相似,但当然不适用于包含空格的文件夹。

奇怪的是,当我直接在shell中执行以下行时,它按预期工作:

find -E "20130117_test" -type f -iregex ".*\/.*\.abc|.*\/.*\.xyz|.*\/.*\.[0-9]{3}" -maxdepth 1 -print0 | xargs -0 7z a -mx=9 -uz1 -x!.DS_Store "20130117_test"/"20130117_test"_data.7z

我知道这个问题与subFolders变量中存储文件夹列表(引号)有关,但我找不到让它正常工作的方法。

我希望有更高级的shell可以帮助我。

2 个答案:

答案 0 :(得分:1)

通常,您不应使用find来尝试生成文件名列表。您尤其不能按照您尝试的方式构建引用列表;引用 in 参数值与引用围绕参数扩展之间存在差异。在这里,您可以使用简单的模式:

shopt -s nullglob

subFolders=(
  *201[0-4][0-1][0-9]*
  *20150[1-6]*
)
for thisFolder in "${subFolders[@]}"; do
  echo "The current subfolder is: $thisFolder"
  to_archive=(
    */*.abc
    */*.xyz
    */*.[0-9][0-9][0-9]
  )
  7z a -mx9 -uz1 -x!.DS_Store "$thisFolder/$thisFolder_data.7z" "${to_archive[@]}"
done

答案 1 :(得分:0)

结合gniourf_gniourf和chepner的输入,我能够生成以下代码,这正是我想要的。

#!/bin/bash

shopt -s nullglob

find -E "$PWD" -type d -maxdepth 1 -regex ".*201[0-5][0-1][0-9].*" -print0 | while IFS="" read -r -d "" thisFolder ; do
  echo "The current folder is: $thisFolder"
  to_archive=( "$thisFolder"/*.[Aa][Bb][Cc] "$thisFolder"/*.[Xx][Yy][Zz] "$thisFolder"/*.[0-9][0-9][0-9] )

  if [ ${#to_archive[@]} != 0 ]
  then
    7z a -mx=9 -uz1 -x!.DS_Store "$thisFolder"/"${thisFolder##*/}"_data.7z "${to_archive[@]}" && rm "${to_archive[@]}"
  fi
done

shopt -s nullglob导致对不匹配字符的无知

find...搜索与正则表达式模式匹配的目录,并使用空分隔符将每个匹配的文件夹流式传输到while循环。

在while循环中我可以安全地引用$thisFolder变量扩展,从而处理可能的空格。

使用绝对路径而不是相对路径指示7z在存档中不创建文件夹