如何按指定规则修改文本文件第四列数值:保留指定范围值并生成指定区间随机数替换
Got it, let's tackle this problem step by step. You already have a solid start with your AWK snippets for matching the keep ranges—now we just need to wrap in the random number generation logic to cover all four rules in a single script.
AWK has a built-in rand() function that generates a float between 0 and 1, which we can scale and shift to fit your required replacement intervals. Here's a complete, self-contained script that handles all your rules:
Complete AWK Script
BEGIN { # Define the "keep" thresholds from your rules neg_keep_low = -2.100552742679913983e-02 neg_keep_high = -1.249582196275393240e-02 pos_keep_low = 1.381056887718538353e-04 pos_keep_high = 2.346095085764924595e-04 # Define replacement random number ranges replace_neg_min = -1.8445493471994996071e-03 replace_neg_max = -1.145493471994996071e-03 replace_pos_min = 1.531056887718538353e-06 replace_pos_max = 1.956056887718538353e-06 # Initialize random seed with current time to get different values each run srand() } # Process every line in the input file { fourth_col = $4 # Check if value falls in one of the "keep" ranges if ((fourth_col >= neg_keep_low && fourth_col <= neg_keep_high) || (fourth_col >= pos_keep_low && fourth_col <= pos_keep_high)) { print $1, $2, $3, fourth_col " # no change" } # Handle negative values that need replacement else if (fourth_col < 0) { # Calculate random value in the negative replacement range rand_val = replace_neg_min + rand() * (replace_neg_max - replace_neg_min) # Format output to match your example's scientific notation precision printf "%s %s %s %.17e # new value\n", $1, $2, $3, rand_val } # Handle positive values that need replacement else { rand_val = replace_pos_min + rand() * (replace_pos_max - replace_pos_min) printf "%s %s %s %.17e # new value\n", $1, $2, $3, rand_val } }
How It Works
BEGINBlock: This runs once before processing any lines. We define all your threshold values here for readability, and initialize the random seed withsrand()so you get unique random numbers every time you run the script.- Keep Rule Check: First, we check if the fourth column falls into either of your "keep" intervals. If yes, we print the line as-is with a comment.
- Negative Replacement: For negative values outside the keep range, we calculate a random number in your specified negative interval using
rand(), then format it to match the scientific notation precision from your examples. - Positive Replacement: Same logic applies to positive values outside the keep range—we generate a random number in the positive replacement interval and format it correctly.
How to Run
Save the script as process_values.awk, then run it against your input file:
awk -f process_values.awk input > output.txt
The processed results will be saved to output.txt.
Example Output
For the lines you provided that need replacement, you'll get output like this (random values will vary per run, but will be within your specified ranges):
2.89999962 2.99699998 -0.00000000 -1.452349347199499607e-03 # new value
0.800000763 2.99699998 -9.37441375E-11 1.721056887718538353e-06 # new value
This should cover all your requirements perfectly!
内容的提问来源于stack exchange,提问作者manas

