如何按位置匹配文件并替换目标文件的指定占位内容(脚本补全)
解决Shell脚本中按组替换文本的问题
嘿,我来帮你补全这个Shell脚本的核心替换逻辑!先再理一遍需求:
- 第一个文件内容是
abc ram bdc jay vlm rock,要按每组2个词拆成3组 - 第二个文件有3行命令,每行都是
grep -f -w '' /d/demo.txt,需要把第一文件的每组内容依次填到每行的空引号里 - 你已经搞定了行数/组数匹配的判断,就差核心替换部分了
完整脚本方案(用xargs+paste+sed实现)
这个方案用基础Shell工具组合,逻辑清晰易懂:
#!/bin/bash # 替换成你实际的文件路径 first_file="./first.txt" second_file="./second.txt" # 计算第一个文件的组数(总词数除以2) total_words=$(wc -w < "$first_file") count_firstfile=$((total_words / 2)) # 计算第二个文件的行数 count_secondfile=$(wc -l < "$second_file") if [ "$count_firstfile" -eq "$count_secondfile" ]; then # 核心替换逻辑 # 1. 把第一文件拆成每行2个词 # 2. 和第二文件的每行对应拼接 # 3. 把每组内容替换到空引号中 xargs -n2 < "$first_file" | paste - "$second_file" | sed "s/''/'PLACEHOLDER'/;s/^\(.*\)\t\(.*\)'PLACEHOLDER'/\2'\1'/;" elif [ "$count_firstfile" -ne "$count_secondfile" ]; then echo "错误:第一个文件的组数($count_firstfile)和第二个文件的行数($count_secondfile)不匹配!" else echo "Nothing to do" fi
核心逻辑拆解
xargs -n2 < "$first_file":把第一个文件的所有单词按每行2个拆分,输出结果是:abc ram bdc jay vlm rockpaste - "$second_file":把上面的每行和第二个文件的对应行用制表符拼接,比如第一行变成:abc ram grep -f -w '' /d/demo.txtsed替换:- 先把空引号
''替换成占位符'PLACEHOLDER',方便后续定位 - 再把制表符前的每组内容移到占位符的位置,最终得到你想要的命令行
- 先把空引号
另一种更灵活的awk方案
如果需要更复杂的处理逻辑,用awk会更灵活:
#!/bin/bash first_file="./first.txt" second_file="./second.txt" total_words=$(wc -w < "$first_file") count_firstfile=$((total_words / 2)) count_secondfile=$(wc -l < "$second_file") if [ "$count_firstfile" -eq "$count_secondfile" ]; then awk -v first="$first_file" ' BEGIN { # 提前读取第一个文件,把每2个词存到数组 while ((getline line < first) > 0) { split(line, words) for (i=1; i<=length(words); i+=2) { groups[++idx] = words[i] " " words[i+1] } } close(first) } # 处理第二个文件的每一行 { # 替换空引号为对应的组内容,\047是单引号的转义写法 sub(/''/, "\047" groups[NR] "\047") print $0 }' "$second_file" elif [ "$count_firstfile" -ne "$count_secondfile" ]; then echo "错误:第一个文件的组数($count_firstfile)和第二个文件的行数($count_secondfile)不匹配!" else echo "Nothing to do" fi
这个awk版本会先把第一文件的所有组提前存到数组里,然后遍历第二文件的每一行,直接替换空引号的位置,逻辑更直观,也方便后续扩展。
内容的提问来源于stack exchange,提问作者rarkatatruenayu
相关产品推荐
相关产品推荐

