Shell -循环处理文件



我正在编写一个shell脚本,并且遇到了需要将参数传递给函数的情况。但目前它并没有像预期的那样起作用。我请求你通过脚本,让我知道我在这里错过了什么。

如果我在脚本文件(test.sh)中直接编写下面的代码,而不使用任何函数,那么它就可以正常工作。

source ./logger.sh
now=$(date +"%Y.%m.%d_%H.%M.%S")
logFile="/path/to/the/directory/${now}.log"
touch $logFile
scriptName="test.sh"
source="/path/to/the/directory"
older=7
while IFS= read -r -d $''; do
printf "nIn while: Currently processing file: ${REPLY}n"
file=$REPLY
log 1 $scriptName "main" "Currently processing file: ${file}" $logFile
done < <(find ${source} -maxdepth 1 -type f -mtime +${older} ! -name '*.FLAG' ! -name '*.FAIL' -print0)

文件

输出
2021-Oct-24 09:37:12            test.sh:    main:   Currently processing file: /path/to/the/directory/file1.txt
2021-Oct-24 09:37:12            test.sh:    main:   Currently processing file: /path/to/the/directory/file2.txt
..... more files ...

但是,当我将脚本封装成函数调用时,它就不能正常工作了。

function moveFiles() {
source=$1
older=$2
logFile=$3
log 1 $scriptName "moveFiles" "Finding files from ${source} which changed before ${older} days." $logFile
while IFS= read -r -d $''; do
printf "nIn while: Currently processing file: ${REPLY}n"
file=$REPLY
log 1 $scriptName "moveFiles" "Currently processing file: ${file}" $logFile
done < <(find ${source} -maxdepth 1 -type f -mtime +${older} ! -name '*.FLAG' ! -name '*.FAIL' -print0)
log 1 $scriptName "moveFiles" "For loop completed" $logFile
}
source ./logger.sh
now=$(date +"%Y.%m.%d_%H.%M.%S")
logFile="/path/to/the/directory/${now}.log"
touch $logFile
scriptName="test.sh"
moveFiles "/path/to/the/directory" 7 $logFile
log 2 $scriptName "main" "Move files - completed" $logFile

文件

输出
2021-Oct-24 09:43:23            test.sh:    moveFiles:  Finding files from /path/to/the/directory which changed before 7 days.
2021-Oct-24 09:43:23            test.sh:    moveFiles:  For loop completed

当我没有函数直接运行脚本时,我得到的输出,我需要通过函数也有相同的输出。请帮我解决这个问题。

另外,我更喜欢循环文件数组,而不是提供查找命令输出到while循环。我找不到任何有效的解决方案,这就是为什么我选择使用这种方法。如果有更好的方法,我肯定会选择那个。

注意:日志功能在我通过source ./logger.sh包含的logger.sh中,它似乎工作良好。

编辑1:我正在寻找一种方法来存储查找命令输出到数组,然后将数组发送到另一个函数,并使用循环在那里处理数组的元素。我能有更好的办法吗?我在下面试过,但它不起作用。数组中总是只有一个元素

list=$(find ${source} -maxdepth 1 -type f -mtime +${older} ! -name '*.FLAG' ! -name '*.FAIL' -print0)
processInLoop ${list[@]}

在另一个函数

function processInLoop(){
fileList=("${@}")
}

提前谢谢你。

在下面的find语句中尝试使用您的目录和过滤器。

function moveFiles() {
source=$1
older=$2
logFile=$3
echo 1 $scriptName "moveFiles" "Finding files from ${source} which changed before ${older} days." $logFile
find ${source} -maxdepth 1 -type f -mtime +1  -name '*' -print0 |
while IFS= read -r -d ''; do
echo "nIn while: Currently processing file: ${REPLY}n"
file=$REPLY
echo $scriptName "moveFiles" "Currently processing file: ${file}" 
$logFile
done
echo $scriptName "moveFiles" "For loop completed" $logFile
}
now=$(date +"%Y.%m.%d_%H.%M.%S")
logFile="."
touch $logFile
scriptName="test.sh"
moveFiles "." 7 $logFile
echo $scriptName "main" "Move files - completed" $logFile

我正在寻找一种方法来存储查找命令输出到数组…

使用readarray

readarray -d '' -t arr < <(find ....)
yourfunction "${arr[@]}"

这个脚本有很多问题——没有引号的变量展开,使用普通变量作为数组,试图在字符串中存储零字节。使用shellcheck检查脚本

引用变量扩展以防止分字和文件名扩展。不做touch $logFile,做touch "$logFile"

$''''相同。每个字符串以零字节结束,两个零字节等于一个零字节,因为字符串直到第一个零字节都是解释器。

主观:我不是pascal case的粉丝,我更喜欢snake case。

list=$(... -print0)-因为字符串最多存储一个零字节,所以不能在变量中存储零字节。您可以通过xxd -p管道将其转换为十六进制,或者像上面所示的那样将其读入数组。你应该得到bash关于它的警告。

list=$(...) ; func ${list[@]}-变量展开没有引号,所以它会进行分词和文件名扩展。list不是数组,所以它只有一个元素。list=$( ... )赋值一个变量,list=( ... )赋值一个数组。

主观:find ... ! ...-虽然在非交互式脚本中禁用历史扩展,但我建议无论如何引用!,这样当您将内容复制到终端以"测试它"时,历史扩展不会被触发。我会输入find ... '!' ...

相关内容

  • 没有找到相关文章

最新更新