使用awk为合并的TXT文件添加无扩展名文件名列遇异常
问题分析与解决
你的脚本为什么出错?
- 语法逻辑错误:你写的
name=$(basename -s .txt $i)| awk...完全搞反了赋值和管道的关系——这行代码是把basename的输出(比如temp、demo)直接通过管道传给awk,而不是把结果赋值给name变量。所以name变量根本没拿到你想要的文件名。 - awk变量引用错误:就算
name变量赋值成功,awk里的$name是用来引用当前行的第N个字段(比如$1是第一列),不是引用shell的name变量。这就导致awk把每行内容和自身拼接,出现你看到的重复输出。
正确的写法
写法1:修正你的shell循环+awk方案
for i in *.txt; do # 先提取无扩展名的文件名 name=$(basename -s .txt "$i") # 用awk的-v参数把shell变量传给awk,直接打印每行+文件名 awk -v fname="$name" '{OFS="\t"; print $0, fname}' "$i" done
写法2:纯awk单命令(更简洁,不用shell循环)
直接利用awk内置的FILENAME变量获取当前处理的文件名,再去掉.txt后缀:
awk '{ OFS="\t" # 复制文件名到临时变量,避免修改内置变量 fname = FILENAME # 去掉末尾的.txt后缀 sub(/\.txt$/, "", fname) print $0, fname }' *.txt
写法3:awk+sed组合(更简短)
awk '{OFS="\t"; print $0, FILENAME}' *.txt | sed 's/\.txt$//'
测试输出
运行上面任意一种写法,都会得到你预期的结果:
adam 12 temp george 15 temp thomas 20 temp mark 8 demo richard 11 demo james 18 demo
内容的提问来源于stack exchange,提问作者Dr. Heinz Doofenshmirtz PhD
相关产品推荐
相关产品推荐

