Regex 用随机值替换文本文件中的图案

Regex 用随机值替换文本文件中的图案,regex,bash,text,sed,awk,Regex,Bash,Text,Sed,Awk,我有一个具有此模式的文本文件: \t (hello world) 我需要将括号中的文本替换为唯一值(例如ob1、obj2等),以便 \t (obj) \t (obj) \t (obj) 变成 \t (obj1) \t (obj2) \t (obj3) 或者其他独一无二的东西。使用在cygwin中工作的任何工具的解决方案都会起作用。我尝试使用bash和sed执行此操作失败: #!/bin/bash x=1 for fl in myfile; do cp $fl $fl.old

我有一个具有此模式的文本文件:

\t (hello world)
我需要将括号中的文本替换为唯一值(例如ob1、obj2等),以便

\t (obj)
\t (obj)
\t (obj)
变成

\t (obj1)
\t (obj2)
\t (obj3)
或者其他独一无二的东西。使用在cygwin中工作的任何工具的解决方案都会起作用。我尝试使用bash和sed执行此操作失败:

#!/bin/bash
x=1
for fl in myfile; do
    cp $fl $fl.old
    sed 's/\\t \(.*\)/\\t \("${x}"\)/g' $fl.old > $fl.new
    x=$((x+1))
    echo $x
done

我知道的最好的方法是使用perl就地编辑:

perl -i.bak -ne '$a=int(rand()*2000); s/\((.*?)\)/{$1$a}/g; print' myfile.txt
例如,myfile.txt包含:

\t (obj)
\t (obj)
\t (obj)
\t (obj1869)
\t (obj665)
\t (obj1459)
运行就地编辑:

perl -i.bak -ne '$a=int(rand()*2000); s/\((.*?)\)/{$1$a}/g; print' myfile.txt
myfile.txt现在包含:

\t (obj)
\t (obj)
\t (obj)
\t (obj1869)
\t (obj665)
\t (obj1459)
显然,根据您的要求调整
2000

编辑:如果希望使用递增标识符,请使用:

perl -i.bak -ne '$a++; s/\((.*?)\)/{$1$a}/g; print' myfile.txt

perl-pe的/(?试试这个正则表达式……它使用sed的“扩展”正则表达式

sed -r -e "s/\t \((.*)\)/\t \1${x}/g"
但是,我不确定您的问题是想让
obj
转到同一文件中的
obj1
obj2
,…还是每个文件都有自己独特的
obj1
obj2

编辑显然,您需要逐行读取文件…类似的方法可能会奏效

x=1
while read line; do echo ${line} |  sed -r -e "s/\t \((.*)\)/\t \1${x}/g"; let "x=x+1"; done < myfile.txt > myfile.new.txt
x=1
在读取行时;执行echo${line}sed-r-e“s/\t\(.*)/\t\1${x}/g”;让“x=x+1”;完成myfile.new.txt

当然,像其他人一样使用
perl可能更简单

+1我的想法是也使用perl。要求之一是唯一性,因此需要跟踪所使用的标识符。使用递增计数器更简单。这似乎不会改变文件的内容(没有错误)。我不懂perl,甚至我都能理解这里发生了什么。我使用的是Cygwin。那条语句中有没有需要转义的字符?@Scribblemacher我刚刚注意到你的两个输入数据示例是不同的,一个使用
{
,另一个使用
)我假设
{
。您可能需要
perl-i.bak-ne'$a++;s/\(.*?)/{$1$a}/g;打印'myfile.txt
,它查找包含在
中的令牌。正是这样。我完全忽略了差异。