我很难使用 IF 语句。
一个目录被传递给脚本,该目录(包含任意数量的子文件夹)将包含.txt
文件或.tmp
文件,我的最终目标是将所有.tmp
文件复制到一个文件夹,并将.txt
文件复制到另一个文件夹。
目前有:
shopt -s nullglob
if [[ -n $(echo *.txt) ]]; then
elif [[ -n $(echo *.tmp) ]]; then
else
echo "nothing Found"
fi
但它不检查子目录。是不是少了点什么?
答案1
您将需要使用以下find
命令:
find "$start_dir" -type f -name '*.txt' -exec cp -t "$txt_destination" '{}' +
find "$start_dir" -type f -name '*.tmp' -exec cp -t "$tmp_destination" '{}' +
答案2
但它不检查子目录。是不是少了点什么?
嗯,普通的 glob 不会递归到子目录。由于您正在使用shopt
,您可能正在使用 Bash,**/
只要您设置 ,它就支持递归 glob 的表示法shopt -s globstar
。设置后,将扩展到当前目录的子目录中也**/*.txt
匹配的所有文件。*.txt
答案3
ikkachu 解释了 bash 可以进行递归通配,但没有说明如何进行。那么,让我们展示一下如何:
shopt -s globstar extglob nullglob
txt_files=(**/!(*test*|*sample*).txt)
if (( ${#txt_files} )); then
cp -t "${txt_files[@]}" $txt_destination
fi
tmp_files=(**/!(*test*|*sample*).tmp)
if (( ${#tmp_files} )); then
cp -t "${tmp_files[@]}" $tmp_destination
fi
如果我没记错的话,zsh 已经能够做到这一点十多年了。如果您使用 zsh 而不是 bash:
setopt extendedglob
txt_files=( **/*.txt~*(test|sample)*(N.) )
if (( $#txt_files )) cp -t $txt_files $txt_destination
tmp_files=( **/*.tmp~*(test|sample)*(N.) )
if (( $#tmp_files )) cp -t $tmp_files $tmp_destination
或者更 C 风格:
setopt extendedglob nullglob
txt_files=( **/*.txt~*(test|sample)*(.) )
if [[ $#txt_files != 0 ]] {
cp -t $txt_files $txt_destination
}
tmp_files=( **/*.tmp~*(test|sample)*(.) )
if [[ $#tmp_files != 0 ]] {
cp -t $tmp_files $tmp_destination
}
我没有忘记那里的任何引语; zsh 跟踪数组元素边界,而不仅仅是打破空格。 [[ ]] 测试后的分号也是可选的。