基于Bash脚本与Sed按规则提取ASCII文件特定位置记录
Got it, let's break this down into manageable parts to solve your problem. You need to process ASCII files with repeating 1NAME blocks (1 to 744 occurrences), extract values from a specific position in each block, output results to a text file with clear headers, and build a flexible Bash+Sed script that handles multiple input files. Here's a step-by-step solution:
1. Block Structure Assumption
I’ll assume each 1NAME block follows a consistent line-based structure (adjust if your actual format differs):
1NAME [Line 1 of block] [Line 2 of block] [Line N of block]
When you mention "specified重复位置的值", I’ll interpret that as the Nth line after the 1NAME header (we can tweak this later if you need to match a field name instead of a line position).
2. Core Sed Logic for Extraction
Sed is ideal for pattern-based line grabbing. To extract the Nth line after every 1NAME entry:
- For the 2nd line (immediately after
1NAME):sed -n '/^1NAME$/{n;p}' your_file.txt - For the 3rd line, add an extra
ncommand:sed -n '/^1NAME$/{n;n;p}' your_file.txt
3. Reusable Bash Script
Save this as extract_1NAME.sh — it lets you specify the target position, output file, and process multiple inputs:
#!/bin/bash # Default configuration TARGET_POSITION=2 # Default to 2nd line after 1NAME OUTPUT_FILE="extracted_results.txt" # Parse command-line arguments while getopts "p:o:" opt; do case $opt in p) TARGET_POSITION="$OPTARG" ;; o) OUTPUT_FILE="$OPTARG" ;; \?) echo "Invalid option: -$OPTARG" >&2; exit 1 ;; esac done # Shift to access input files after flags shift $((OPTIND - 1)) # Check if input files are provided if [ $# -eq 0 ]; then echo "Usage: $0 -p <position> -o <output_file> <input_files...>" echo "Example: $0 -p 3 -o my_results.txt data1.txt data2.txt" exit 1 fi # Generate dynamic Sed command: add (POSITION-1) number of 'n' commands SED_SCRIPT="/^1NAME$/{$(printf 'n;' $(seq 1 $((TARGET_POSITION - 1))))p}" # Write CSV header to output echo "Input_File,Extracted_Value_Position_$TARGET_POSITION" > "$OUTPUT_FILE" # Process each input file for FILE in "$@"; do # Extract values and append to output (with filename context) sed -n "$SED_SCRIPT" "$FILE" | while read -r VALUE; do echo "$FILE,$VALUE" >> "$OUTPUT_FILE" done done echo "Done! Results saved to $OUTPUT_FILE"
4. How to Use
- Make the script executable:
chmod +x extract_1NAME.sh - Run with your parameters:
- Example: Extract the 3rd line after
1NAMEfrom two files, output toresults.csv:./extract_1NAME.sh -p 3 -o results.csv file1.txt file2.txt
- Example: Extract the 3rd line after
5. Example Output
If file1.txt has:
1NAME Apple Red Round 1NAME Banana Yellow Long
Running the example command will produce results.csv:
Input_File,Extracted_Value_Position_3 file1.txt,Round file1.txt,Long
6. Adjustments for Named Fields
If your blocks use labeled fields (e.g., Color: Red), replace the SED_SCRIPT line with this to match field names instead of line positions:
SED_SCRIPT='/^1NAME$/{:loop;n;/Color:/{s/.*: //;p};b loop}'
This searches each 1NAME block for the Color: line, strips the label, and extracts the value.
内容的提问来源于stack exchange,提问作者coding_Stumps_me

