Bash脚本中参数列表内目标单词索引无法赋值给变量的问题及替代实现方法咨询
Got it, let's break down what's going wrong with your script first, then cover some more robust ways to find the index of your target word in the argument list.
Why Your Variable Assignment is Failing
The error happens because you're trying to execute the arguments stored in ALL_ARGS as a command instead of piping their value into your grep/sed chain. Also, your elif line is missing a semicolon after the condition, which is a subtle Bash syntax requirement.
Here's the fixed version of your code snippet:
elif [[ "$#" -gt 0 ]]; then ALL_ARGS="$@" # The working echo command you had echo "${ALL_ARGS}" | grep -b -o target | sed 's/:.*$//' # Fixed variable assignment using proper command substitution TARGET_INDEX=$(echo "${ALL_ARGS}" | grep -b -o target | sed 's/:.*$//') echo "$TARGET_INDEX" fi
Key fixes:
- Added a semicolon
;after[[ "$#" -gt 0 ]]to satisfy Bash syntax rules - Used
$(...)(modern command substitution) instead of backticks (though backticks work too,$(...)is easier to read and nest) - Wrapped
ALL_ARGSin quotes"${ALL_ARGS}"to preserve spaces correctly in your arguments
Alternative Methods to Find the Target Word Index
If you want more flexibility or avoid external commands, here are a few options:
1. Pure Bash (No External Commands)
This uses Bash parameter expansion to calculate the index without calling grep/sed. It works for the first occurrence of your target word:
elif [[ "$#" -gt 0 ]]; then ALL_ARGS="$@" target="target" # Get everything before the first occurrence of $target prefix="${ALL_ARGS%%$target*}" # The length of the prefix is the 0-based index of the target word TARGET_INDEX=${#prefix} echo "$TARGET_INDEX" fi
This is faster because it doesn't spawn external processes, and it handles spaces in arguments correctly.
2. Using awk for Multiple Occurrences
If you need to find all positions of the target word (not just the first), awk is a great tool:
elif [[ "$#" -gt 0 ]]; then ALL_ARGS="$@" target="target" # Print all 0-based indices of the target word echo "${ALL_ARGS}" | awk -v t="$target" '{ idx = index($0, t) while (idx > 0) { print idx - 1 # Convert awk's 1-based index to 0-based idx = index(substr($0, idx + length(t)), t) + idx + length(t) - 1 } }' fi
3. Using Perl for Advanced Matching
Perl makes it easy to iterate over all matches and get their positions:
elif [[ "$#" -gt 0 ]]; then ALL_ARGS="$@" # Print all 0-based indices of "target" echo "${ALL_ARGS}" | perl -n -e 'while (/target/g) { print pos() - length($&), "\n" }' fi
This works for regex patterns too, if you ever need to match more complex strings than a fixed word.
内容的提问来源于stack exchange,提问作者Murtrag

