如何用awk实现管道输入写列及将统计行数写入指定文件列?
Hey there! Let's walk through how to tackle both of your requirements, plus share some optimized approaches to make things cleaner and more efficient.
1. Writing Pipe Input to Specific Columns of a File with awk
First up: taking input from a pipe and writing it to a specific column in another file. Let's cover two common scenarios:
Scenario A: Append a new column from pipe input
If you want to add the pipe input as a new column (say, the 2nd column) to an existing file target.txt:
# Replace `your_input_command` with whatever generates your pipe input (e.g., cat input.txt) your_input_command | awk 'NR==FNR{a[NR]=$0; next} {print $0, a[FNR]}' - target.txt > temp.txt && mv temp.txt target.txt
- How this works:
NR==FNRtells awk to first process the standard input (marked by-), storing each line in an arrayaindexed by line number.- Then it processes
target.txt, appending the corresponding line from arrayato each row. - We write to a temp file first and replace the original to avoid corrupting
target.txtif something goes wrong.
Scenario B: Replace an existing column with pipe input
If you need to overwrite an existing column (like the 3rd column) instead of adding a new one:
your_input_command | awk 'NR==FNR{a[NR]=$0; next} {$3=a[FNR]; print}' - target.txt > temp.txt && mv temp.txt target.txt
Here, $3=a[FNR] replaces the 3rd column value with the matching line from your pipe input.
Optimized Tip
If your pipe input and target file have mismatched line counts, you can extend the awk script to handle it gracefully (e.g., keep original column values for extra lines in the target, or add new lines for extra input):
your_input_command | awk ' NR==FNR{a[NR]=$0; max_input=NR; next} { if(FNR <= max_input) $3=a[FNR] print } END{ for(i=FNR+1; i<=max_input; i++) print "", "", a[i] } ' - target.txt > temp.txt && mv temp.txt target.txt
2. Writing Line Count to the 3rd Column of count.txt
Your goal is to take the line count of list (which you get as 68) and write it to the 3rd column of count.txt. Let's break this down:
First: Get the line count efficiently
Instead of wc -l list | awk '{print $1}', you can simplify this to:
line_count=$(wc -l < list)
This directly outputs just the number (no filename attached), so you don't need awk to extract it—cleaner and slightly faster.
Scenario A: Replace the 3rd column in an existing count.txt
If count.txt already has rows and you want to set the 3rd column of every row to the line count:
awk -v cnt="$line_count" '{$3=cnt; print}' count.txt > temp.txt && mv temp.txt count.txt
- The
-v cnt="$line_count"passes the shell variable into awk, so we can usecntto update the 3rd column.
Scenario B: Create a new row with the line count in the 3rd column
If you want to add a new line to count.txt where only the 3rd column is the line count:
# Using printf for consistent spacing (tabs here) printf "%s\t%s\t%s\n" "" "" "$line_count" >> count.txt # Or with awk if you prefer: awk -v cnt="$line_count" 'END{print "", "", cnt}' count.txt >> count.txt
Optimized Tip
If count.txt is empty and you just need a single row with the 3rd column as the line count, skip the append and write directly:
printf "%s\t%s\t%s\n" "" "" "$(wc -l < list)" > count.txt
内容的提问来源于stack exchange,提问作者M. Kaan

