Bash文本解析:参数替换困惑及awk/sed变量解析方法问询
I get it—frustrating when you’re trying to pull specific variable values from a file and end up with the whole thing printed instead! Let’s break this down step by step, using common tools like awk and sed, and show how to define your target variables and extract their values correctly.
First, let’s assume your structured file (let’s call it config.txt) looks like this—a typical config file format:
DB_HOST=localhost DB_PORT=5432 APP_NAME="My Cool App" DEBUG=false # This is a comment line API_KEY=abc123xyz
Let’s say you want to extract values for DB_HOST, APP_NAME, and API_KEY—that’s your target variable list.
Why Your Script Might Be Printing the Whole File
A common mistake is forgetting to suppress default output in tools like sed, or using a pattern that’s too broad. For example, if you ran sed 's/.*DB_HOST=\(.*\)/\1/' config.txt, sed will replace the matching line but print every line (including non-matching ones) by default. Adding -n fixes that.
Method 1: Using awk (Flexible for Multiple Variables)
Awk is great here because it lets you pass your target variable list directly and match against it.
First, define your target variables in the shell:
TARGET_VARS="DB_HOST APP_NAME API_KEY"
Then use awk to parse the file:
awk -v vars="$TARGET_VARS" ' BEGIN { # Split the target variables into an array split(vars, target_list, " ") for (i in target_list) { wanted[target_list[i]] = 1 # Mark variables we want to extract } } # Match lines that start with a valid variable name followed by = /^[A-Za-z_][A-Za-z0-9_]*=/ { # Extract the variable name (everything before =) var_name = substr($0, 1, index($0, "=")-1) # If this variable is in our wanted list, print its value if (var_name in wanted) { var_value = substr($0, index($0, "=")+1) print var_name ": " var_value # Or if you want just the value: print var_value } }' config.txt
This will output exactly the variables you want:
DB_HOST: localhost APP_NAME: "My Cool App" API_KEY: abc123xyz
If you want to assign these values directly to shell variables, modify the awk output to generate shell commands and evaluate them:
eval $(awk -v vars="$TARGET_VARS" ' BEGIN { split(vars, target_list, " "); for (i in target_list) wanted[target_list[i]]=1 } /^[A-Za-z_][A-Za-z0-9_]*=/ { var_name = substr($0,1,index($0,"=")-1) if (var_name in wanted) { var_value = substr($0,index($0,"=")+1) print var_name "=\"" var_value "\"" } }' config.txt) # Now you can use the variables in your shell: echo "DB Host is $DB_HOST" echo "API Key is $API_KEY"
Method 2: Using sed (Simple for Specific Variables)
If you prefer sed, make sure to use -n to suppress default line printing, and use p to print only the matched lines.
Extract a single variable:
sed -n 's/^DB_HOST=\(.*\)/\1/p' config.txt
Output: localhost
Extract multiple variables:
You can chain patterns with -e, or use a regex that matches any of your target variables:
# Define target variables (escape | for regex) TARGET_VARS="DB_HOST\|APP_NAME\|API_KEY" sed -n "s/^\($TARGET_VARS\)=\(.*\)/\2/p" config.txt
Output:
localhost "My Cool App" abc123xyz
Method 3: Shell Loop with grep/cut (Straightforward)
If you want to stick to basic shell tools, a loop works too:
# Define your target variables as an array target_vars=("DB_HOST" "APP_NAME" "API_KEY") for var in "${target_vars[@]}"; do # Extract the value using grep and cut value=$(grep "^$var=" config.txt | cut -d'=' -f2-) echo "$var = $value" # To assign to a shell variable: # export "$var=$value" done
This will give you the same targeted output as the other methods.
内容的提问来源于stack exchange,提问作者user3285014

