简体   繁体   English

变量分配之间的差异

[英]Difference between variable assignments

I had a question that was answered here: https://unix.stackexchange.com/questions/264925/awk-fs-with-back-slashes 我有一个在这里回答的问题: https : //unix.stackexchange.com/questions/264925/awk-fs-with-back-slashes

After that I tried adding it to a .sh script that starts with: 之后,我尝试将其添加到以以下内容开头的.sh脚本中:

#!/bin/bash

My Line: 我的专线:

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

And then I print the output using: 然后我使用以下命令打印输出:

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

But this gives me the error: 但这给了我错误:

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

If I change the line to be: 如果我将行更改为:

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

Then it works as expected. 然后它按预期工作。

I'm assuming that the problem was with using the back tick characters, but I don't understand why. 我假设问题出在使用反勾字符,但是我不明白为什么。 Probably because I don't understand the behavior of ` vs ' vs " . If anyone can point me to documentation that can explain this behavior (maybe tldp) then it would be greatly appreciated. 可能是因为我不理解的行为` VS ' VS " 。如果任何人都可以点我的文档,可以解释这种行为(也许TLDP),那么将不胜感激。

The backquote (`) is used in the old-style command substitution, The foo=$(command) syntax is recommended instead. 在旧式命令替换中使用反引号 (`),建议使用foo=$(command)语法。 Backslash handling inside $() is less surprising, and $() is easier to nest. $()反斜杠处理不足为奇,而$()更易于嵌套。 See BashFAQ82 BashFAQ82

Using backquotes, you'll have to escape required sequence for gawk : 使用反引号,您必须转义gawk必需序列:

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

Aside: Feed categoryFilenames array in a loop instead: 另外:循环中输入categoryFilenames数组:

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

Now it is safer to iterate over categoryFilenames like you did, but with double-quotes: 现在,像您一样遍历categoryFilenames更加安全,但使用双引号:

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

Don't forget to "Double quote" every literal that contains spaces/metacharacters and every expansion: "$var" , "$(command "$var")" , "${array[@]}" , "a & b" . 不要忘记对每个包含空格/元字符和每个扩展名的文字进行“双引号”"$var""$(command "$var")""${array[@]}""a & b"

Instead of find , just iterate over all the files in the current directory, and use the shell to process only regular files and extract the file name. 代替find ,只需遍历当前目录中的所有文件,并使用Shell仅处理常规文件并提取文件名。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM