逐行读取文件替换对应内容为大写的Shell脚本实现问题求助
正确实现方案及问题分析
原脚本的问题
你写的脚本存在两个核心问题:
- 重复输出全文件:每次循环都会完整读取并处理
f2.txt,因为f1.txt有两行,最终会输出两次处理后的f2.txt内容,而非累积替换结果。 - 替换逻辑错误:
sed -e 's/\(.*\)/\U\1/'是把整行文本全部转大写,并没有针对f1.txt中的每行字符串做精准替换。
可行实现方案
方案一:用Sed生成替换规则(高效简洁)
通过先将f1.txt的内容转换为Sed替换命令,再一次性处理f2.txt:
sed -e 's/^/s\//; s/$/\//; s/\/$/\U&\/g/' f1.txt | sed -f - f2.txt
逻辑解析:
- 第一个
sed命令将f1.txt的每一行L转换为Sed替换规则:s/^/s\//:在行首添加s/s/$/\//:在行尾添加/s/\/$/\U&\/g/:将行尾的/替换为\U&/g,最终生成s/L/\UL/g(\U用于将匹配内容转大写,g表示全局替换)
- 通过管道将生成的规则传递给第二个
sed,-f -表示从标准输入读取替换规则,处理f2.txt。
方案二:用Awk实现(兼容特殊字符)
如果f1.txt中包含Sed特殊字符(如/、&),Awk的实现更省心:
awk 'NR==FNR { map[$0] = toupper($0); next } { for (k in map) gsub(k, map[k]); print }' f1.txt f2.txt
逻辑解析:
NR==FNR:处理第一个文件f1.txt时,将每行字符串作为键,对应值存为该字符串的大写形式。- 处理
f2.txt时,遍历所有存储的键,将每行中匹配的字符串替换为对应大写值,最后打印该行。
测试验证
用你提供的示例文件测试上述方案,都会得到预期输出:
st SONE STWO so
内容的提问来源于stack exchange,提问作者albertkao9
相关产品推荐
相关产品推荐

