I had a question that was answered here: https://unix.stackexchange.com/questions/264925/awk-fs-with-back-slashes
After that I tried adding it to a .sh script that starts with:
#!/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.
2 Answers 2
The backquote (`) is used in the old-style command substitution, The foo=$(command) syntax is recommended instead. Backslash handling inside $() is less surprising, and $() is
easier to nest. See BashFAQ82
Using backquotes, you'll have to escape required sequence for gawk:
category1Filenames=(`find . -maxdepth 1 -type f | gawk 'BEGIN { FS = "(\\\./)|(\\\.)" } ; { print 2ドル }' | sort -u`)
Aside: Feed categoryFilenames array in a loop instead:
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:
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".
3 Comments
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.
for name in *; do
[[ -f $name ]] || continue
name_only=${name%%.*}
printf "%s\n" "$name_only"
done
gawksupposed to do? It would be much simpler to just iteratefor genericFilename in *; do [[ -f $genericFilename ]] || continue; ...; done.