如何用越来越多的数字替换单词?

如何用越来越多的数字替换单词?

例如,file.txt 中唯一的内容如下所示:

xxxxxxxxxHAHAxxxxxxHOHOxxxxxxx  

我希望用 seq 1 3 替换 HAHA,用 seq 5 7 替换 HOHO,所以输出应该是:

xxxxxxxxx1xxxxxx5xxxxxxx   
xxxxxxxxx2xxxxxx6xxxxxxx   
xxxxxxxxx3xxxxxx7xxxxxxx   

我做了什么:

for i in $(seq 1 3)    
do  sed "s/HAHA/$i/g" file.txt   
  for i in $(seq 5 7)    
  do sed "s/HOHO/$i/g" file.txt   
  done   
done > new.txt     

但 new.txt 没有显示我所期望的。我应该如何更改代码?

答案1

这是一种方法,可以使用bash内置read命令读取不同文件描述符的功能:

while read -u3 i && read -u4 j; do 
    sed -e "s/HAHA/$i/" -e "s/HOHO/$j/" file.txt
done > new.txt 3< <(seq 1 3) 4< <(seq 5 7)

seq由于您的数字具有简单的算术关系,因此使用单个进程+一些 shell 算术会更简单:

for i in $(seq 1 3); do
  sed -e "s/HAHA/$i/" -e "s/HOHO/$((i+4))/" file.txt
done > new.txt

无论哪种情况,请参阅为什么使用 shell 循环处理文本被认为是不好的做法?- 对于您提供的最小示例来说,效率低下可能并不重要,但如果您正在做更严肃的事情,您应该考虑使用不同的方法。

答案2

无需为生成的每行调用外部实用程序:

read template <file

paste <(seq 1 3) <(seq 5 7) |
while read x y; do
    t=${template/HAHA/$x}
    t=${t/HOHO/$y}
    printf '%s\n' "$t"
done >new.txt

file这首先从名为into 的文件中读取行$template。然后它为循环构造一个两列输入while read。循环的输入是来自 的两列数字seq

在循环中,bash对 的值执行一些特定的替换,以将和字符串$template替换为从 读取的数字。这将创建然后输出。HAHAHOHOpaste$t


仅使用awk,并假设输入仅为一行:

awk '{
         for (i = 1; i <= 3; ++i) {
             t = $0;
             sub("HAHA",   i, t)
             sub("HOHO", 4+i, t)
             print t
         }
     }' file

一个 shell 循环 for bash,模仿awk上面的代码:

read template <file

for (( i = 1; i <= 3; ++i )); do
    t=${template/HAHA/$i}
    t=${t/HOHO/$((i+4))}
    printf '%s\n' "$t"
done

相关内容