在 bash 中使用变量/数组(包括文件名)时如何探测文件名中的引号?

在 bash 中使用变量/数组(包括文件名)时如何探测文件名中的引号?

我已经研究 bash 脚本几天了,并被包含单引号和双引号的文件名所困扰。我想迭代目录中的以下文件:

'file1.txt'
'file2.txt'
"file3.txt"
file"3.txt
file'4.txt
very 'bad file.txt
also "very bad.txt

我知道这是不好的文件命名 - 但你知道,并不是所有人都是程序员并且知道如何正确命名文件。所以我尝试处理这种边缘情况。

我想循环遍历这些文件并在一些 if 语句中使用它们,例如:

dir="my/dir/"
files="$(ls -N "$dir"*)"

shopt -s extglob

for f in $files; do
  if [[ "$files" =  *"(*.png|*.jpg|*.jpeg|*.JPG|*.JPEG|*.webp)" ]]; then
    for $e in "$files"; do
      cp "$e" "$dir""somefilename.pdf"
    else
      cp "$f" "$dir""somefilename.pdf"
  fi
done

现在问题出现了,bash 正在解释文件名中的双引号和单引号并分割文件 - 错误随之而来......

所以我的问题是:如何在 bash 中处理这些情况?

答案1

不要解析 的输出ls。那就是疯狂和各种冲突。如果您尝试对给定目录中的所有文件执行操作,请让 shell 为您处理文件名:

workdir="/path/to/directory"
for file in "${workdir}"/*; do
    case "$file" in
        *.png|*.jpg|*.jpeg|*.JPG|*.JPEG|*.webp)
            cp -- "$file" "$dir"/"somefilename.pdf"
            ;;
    esac
done

请注意,我直接从您的问题中获取了谓词,该谓词具有重复覆盖somefile.pdf每个匹配文件的可疑逻辑,这可能不是您想要的。解决这个问题超出了迭代文件问题的范围,简短的答案是简单地使用for file in path/to/place/*; do stuff_to "$file"; done.

相关内容