Issue
My bash script uses an associative array to find the pattern defined as the word before the first _
in the file name and then do some operations on it.
# the root directory of the script
output=$(pwd)
# the folder with input images
img=$output/!img
declare -A patterns
find_patterns() {
for f in $img/*.png ; do
pattern=${f%%_*} # Remove everything after the first underscore.
pattern_without_path=("${pattern[@]##*/}") # remove path from the pattern
patterns[$pattern_without_path]=1 # add it to the array
done
}
# see found patterns in the array
check_patterns() {
for pat in "${!patterns[@]}"; do
echo $pat
done
}
The issue is the $pattern_without_path
which does not work for ANY path. E.g. when one of the subfolders contains _
the pattern matches the folder name rather then the name of the image.
How could I remove the path automatically for any location of the folder with script / input folders with processed files?
Solution
The issue with the
$pattern_without_path
which does not work for ANY path. E.g. when one of the subfolder contains "_" the pattern recognized as the folder name rather then the name of the image ..
Yes. You are trimming the whole path at the first _
character. If that appears in one of the folder names then you thereby lose any information about anything later in the path. When you trim off the leading folders in what's left, you leave a fragment of a folder name rather than of the ultimate file name.
How could I remove the path automatically for any location of the folder with script / input folders with processed files ?
To avoid issues with paths through folders containing the _
character, remove the path first, then trim the _*
tail.
Note also that your script is under-quoted, and here ...
pattern_without_path=("${pattern[@]##*/}")
... you are setting the value of pattern_without_path
to a one-element array, which appears to be a mistake (albeit one that may not be causing an actual failure). Furthermore, you are treating pattern
as if its value were an array, which it is not.
This would work better:
declare -A patterns
find_patterns() {
for f in "$img"/*.png ; do
image_basename="${f##*/}"
patterns["${image_basename%%_*}"]=1
done
}
Answered By - John Bollinger Answer Checked By - Candace Johnson (WPSolving Volunteer)