变量赋值的区别

Difference between variable assignments

我有一个问题在这里得到了回答: https://unix.stackexchange.com/questions/264925/awk-fs-with-back-slashes

之后,我尝试将它添加到 .sh 以以下开头的脚本:

#!/bin/bash

我的线路:

category1Filenames=(\`find . -maxdepth 1 -type f |
gawk 'BEGIN { FS = "(\\./)|(\\.)" } ; { print  }' | sort -u\`)

然后我使用以下方法打印输出:

for genericFilename in ${category1Filenames[@]}; do  
  printf "%s\n" $genericFilename  
done 

但这给了我错误:

gawk: cmd. line:1: warning: escape sequence `\.' treated as plain `.'

如果我将行更改为:

category1Filenames=$(find . -maxdepth 1 -type f |
gawk 'BEGIN { FS = "(\\./)|(\\.)" } ; { print  }' | sort -u)

然后它按预期工作。

我假设问题出在使用反引号字符上,但我不明白为什么。可能是因为我不理解 ` vs ' vs " 的行为。如果有人可以向我指出可以解释此行为的文档(可能是 tldp),那么将不胜感激。

backquote (`) 用于旧式命令替换,建议使用 foo=$(command) 语法。 $() 中的反斜杠处理并不令人惊讶,而 $() 是 更容易筑巢。参见 BashFAQ82

使用反引号,您必须转义 gawk:

所需的序列
category1Filenames=(`find . -maxdepth 1 -type f | gawk 'BEGIN { FS = "(\\./)|(\\.)" } ; { print  }' | sort -u`)

旁白:改为在循环中输入 categoryFilenames 数组:

while read -r line; do
    categoryFilenames+=("$line")
done < <(find . -maxdepth 1 -type f | gawk 'BEGIN { FS = "(\./)|(\.)" } ; { print  }' | sort -u)

现在像您一样遍历 categoryFilenames 更安全,但使用双引号:

for genericFilename in "${category1Filenames[@]}"; do  
  printf "%s\n" "$genericFilename"  
done  

不要忘记 "Double quote" 每个包含 spaces/metacharacters 和 every 扩展的文字:"$var", "$(command "$var")", "${array[@]}", "a & b".

而不是find,只需遍历当前目录中的所有文件,并使用shell仅处理常规文件并提取文件名。

for name in *; do
    [[ -f $name ]] || continue
    name_only=${name%%.*}
    printf "%s\n" "$name_only"
done