awk gsub问题

awk gsub问题

我过去曾使用 awk 进行大型文件操作和替换。最近,我用它来替换字母 A,并将其替换为一组字符:

$ awk '{gsub(/A/,"@@@")}1' in.txt >> out.txt

其中 in.txt 包含各种长度的字母字符串。(AAA、BBB、CCC、ABABAB 等)

后来编辑:我正在使用 Ubuntu 的 WSL 版本。另外,我考虑过 sed,但它对大型文本文件不太适用。

如何使用 gsub 将文件中的所有字符 A 替换为 @@@、B 替换为 ###、C 替换为 %%% 等

我猜应该接近于:

$ awk '{gsub(/A|B|C/,"&123")}1' in.txt > out.txt

非常感谢!

后来编辑:我在 Win10 上使用 WSL 版本的 Ubuntu。另外,我考虑过使用 sed,但它对大文件不太适用。

答案1

gsub 不适合这个任务。迄今为止最简单的方法是使用 tr 命令:

cat in.txt | tr 'ABC' '@#%' > out.txt

并检查输出:

cat out.txt
@@@, ###, %%%, @#@#@#

答案2

据我所知,awkgsub只能进行简单的文本替换。但是,您可以重复使用该match函数来实现基于哈希的查找和子字符串替换 - 类似于:

awk '
  BEGIN{c["A"]="@@@"; c["B"]="###"; c["C"]="%%%"} 
  {
    while(match($0,/[A-C]/)) {
      $0 = substr($0,1,RSTART-1) c[substr($0,RSTART,1)] substr($0,RSTART+1,length($0)-RSTART)
    }
  }
  1
' in.txt

相比之下,perl s/patt/repl/g(大致相当于 awk 的gsub)有一个可选e标志,允许在 RHS 上执行代码。因此你可以执行类似

perl -pe 'BEGIN{%c = (A => "@@@", B => "###", C => "%%%")} $_ =~ s/[A-C]/$c{$&}/ge' in.txt

这可能更接近您所想的。

相关内容