如何在Bash中将TXT文件格式化为结构化CSV文件?以及如何处理OpenSuse Leap 15.2服务器的CPU温度与风扇转速数据文件?
Absolutely, you can tackle this formatting task with both Awk (which might be more concise) and pure Bash scripting. Let's break down the solutions tailored to your exact needs—taking lines of single values and grouping every two into a comma-separated pair, with pairs separated by spaces (or we can adjust to newlines for standard CSV, which is often better for plotting tools).
Awk Solution (Quick & Clean)
This one-liner will match your desired output format perfectly. It reads your input file, groups every two lines into a temp,fanspeed pair, then joins all pairs with spaces:
awk 'NR%2{prev=$0;next} {print prev","$0}' input.txt | paste -sd ' ' -
How it works:
NR%2{prev=$0;next}: For every odd-numbered line (1st, 3rd, etc.), store the value in theprevvariable and skip to the next line.{print prev","$0}: For even-numbered lines, combine the stored temperature with the current fan speed into a comma-separated pair.paste -sd ' ' -: Takes all the pair lines from Awk and joins them with spaces, resulting in your requested47,1400 75,3800structure.
If you prefer each pair on its own line (the standard CSV format, which is easier for most plotting tools to parse), just skip the paste step:
awk 'NR%2{prev=$0;next} {print prev","$0}' input.txt > formatted_data.csv
This will output:
47,1400 75,3800
Pure Bash Script Solution
If you want to stick to native Bash without external tools like Awk, here's a script that achieves the same goal:
#!/bin/bash input_file="input.txt" output_file="formatted_data.txt" # Track the first value in each pair (CPU temp) temp_value="" while read -r current_value; do if [ -z "$temp_value" ]; then # Store the first value as CPU temperature temp_value="$current_value" else # Combine with fan speed and write to output echo -n "$temp_value,$current_value " >> "$output_file" # Reset for the next pair temp_value="" fi done < "$input_file" # Add a clean newline at the end of the file echo >> "$output_file"
How to use it:
- Save the script as
format_data.sh - Make it executable:
chmod +x format_data.sh - Run it:
./format_data.sh
Bonus Tip for Your Data Collection Workflow
Since you're collecting data every 20 seconds, you can pipe the output of your data collection command directly into either solution to skip the intermediate text file. For example:
# Replace `your_data_collector_cmd` with your actual command that outputs one value per line your_data_collector_cmd | awk 'NR%2{prev=$0;next} {print prev","$0}' > realtime_cpu_fan.csv
If you ever need to handle edge cases (like an odd number of lines in your input), we can tweak these solutions to add placeholders or flag the unpaired value—just let me know!
内容的提问来源于stack exchange,提问作者Planetdragon

