如何让grep匹配bash脚本数组变量中的所有目标数值?
The issue in your script is that when you use grep $threshold dffile, Bash only expands $threshold to the first element of the array ("2%"), so grep never looks for "6%" which is present in your df output. Here's how to fix it and improve the script:
Why It Fails
In Bash, referencing an array with just the variable name ($threshold) returns only the first element. To access all elements, you need to use syntax like ${threshold[@]} or ${threshold[*]}, but you also need to format them correctly for grep to interpret as multiple patterns.
Solution 1: Use Extended Regex with OR Separators
Modify the grep line to join all array elements into a single regex pattern separated by | (OR):
grep -E "$(IFS='|'; echo "${threshold[*]}")" dffile >> thresh
IFS='|': Temporarily sets the internal field separator to|so when we expand${threshold[*]}, elements are joined with|.-E: Enables extended regex, so grep recognizes|as an OR operator.
Solution 2: Read Patterns from Process Substitution
If you prefer to avoid regex (e.g., if your patterns might contain special regex characters), use grep's -f option to read patterns from a process substitution:
grep -f <(printf "%s\n" "${threshold[@]}") dffile >> thresh
printf "%s\n" "${threshold[@]}": Prints each array element on its own line.<(...): Creates a temporary file-like object that grep reads patterns from via-f.
Corrected Full Script
Here's your script with the first solution applied, plus optional cleanup to remove unnecessary intermediate files:
#!/bin/bash threshold=("2%" "6%") # Combine df output, grep matching thresholds, extract mount points, and process df -h | grep -E "$(IFS='|'; echo "${threshold[*]}")" | awk '{print $6}' | while IFS= read -r mount_point do find "$mount_point" -xdev -size +40M -exec ls -lah {} \; | head -n 10 done
This version eliminates intermediate files (dffile, thresh, finding1) by piping commands directly, making the script more efficient and cleaner.
Testing with Your df Output
Given your test server's df output, the corrected grep will match the line with 6% /, extract / as the mount point, and run the find command on / to list large files.
内容的提问来源于stack exchange,提问作者Blake Smreker

