【问题标题】:Replacing a pattern in a text file with a random value用随机值替换文本文件中的模式
【发布时间】:2012-05-18 01:06:34
【问题描述】:

我有一个带有这种模式的文本文件:

\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

【问题讨论】:

    标签: regex bash text sed awk


    【解决方案1】:

    我知道如何做到这一点的最好方法是使用 perl 就地编辑:

    例如myfile.txt 包含:

    \t (obj)
    \t (obj)
    \t (obj)
    

    运行就地编辑:

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

    myfile.txt 现在包含:

    \t (obj1869)
    \t (obj665)
    \t (obj1459)
    

    显然根据您的要求调整2000

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

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

    【讨论】:

    • +1 我的想法是也使用 perl。要求之一是唯一性,因此需要跟踪使用的标识符。使用递增计数器更简单。
    • 这似乎并没有改变文件的内容(没有错误)。我不知道 perl,甚至我也可以了解这里发生的事情。我正在使用 Cygwin。该语句中是否有任何字符需要转义?
    • @Scribblemacher 我刚刚注意到您的两个输入数据示例不同,一个使用{,一个使用(,这可能是问题所在,我假设{
    • 您可能需要perl -i.bak -ne '$a++; s/\((.*?)\)/{$1$a}/g; print' myfile.txt 来查找包含在() 中的令牌。
    • 就是这样。我完全忽略了差异。
    【解决方案2】:
    perl -pe 's/(?<=[(])[^)]*/"obj" . ++$count/eg'
    

    【讨论】:

      【解决方案3】:

      试试这个正则表达式...它使用 sed 的“扩展”正则表达式。

      sed -r -e "s/\t \((.*)\)/\t \1${x}/g"
      

      但是,我不确定您的问题是否希望 obj 转到 obj1obj2、... 在同一个文件中,或者每个文件是否都有自己独特的 obj1、@987654326 @...

      编辑显然你需要逐行读取文件......这样的事情可能会起作用。

      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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多