如何将RANDOM字符串附加到文件中所有出现的另一个字符串

时间:2012-02-09 15:29:16

标签: regex string perl bash

我正在尝试编写一个bash脚本来修改文件中某个字符串的所有匹配项。

我有一个包含大量文本的文件,其中包含网址。所有网址都采用以下格式:http://goo.gl/abc23(即goo.gl/,后跟4或5个字母数字字符)。

我想做的是在所有网址上附加一个字符串。我设法(在用户Dan Fego的帮助下)使用sed完成此操作,但它只能通过附加静态字符串来实现。

我正在寻找的方法是为每次出现添加不同的字符串。假设我有一个函数generatestring,每次都会回显一个不同的字符串。我想为每个网址添加不同的生成字符串。 http://goo.gl/abc23将成为http://goo.gl/abc23?GeneratedString1http://goo.gl/JB007将成为http://goo.gl/JB007?GeneratedString2,依此类推。

有谁知道这是否可以做到?我被告知perl是要走的路,但我对perl没有经验。这就是我在这里问的原因。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

ETA:假设网址嵌入在其他文字中:

$ perl -lnwe 's#http://goo.gl/\w{5}\K\b# "?" . rand(100) #ge; print' googl.txt

例如:

$ cat googl 
random text here, and perhaps some html <a href="http://goo.gl/abc23">
more stuff http://goo.gl/abc23 foo fake link http://foo.bar/abc12
longer http://goo.gl/abc23123123 foo fake link http://foo.bar/abc12
$ perl -lnwe 's#http://goo.gl/\w{5}\K\b# "?" . rand(100) #ge; print' googl
random text here, and perhaps some html <a href="http://goo.gl/abc23?69.998515">
more stuff http://goo.gl/abc23?26.186867532985 foo fake link http://foo.bar/abc12
longer http://goo.gl/abc23123123 foo fake link http://foo.bar/abc12

-l chomps该文件并向print.添加换行符-n在脚本周围添加while(<>)循环,这基本上意味着它从参数文件中读取名字或来自STDIN。 \K表示“保留匹配的文字”,\b是字边界,因此您不匹配部分字符串。

请注意它仍会匹配http://goo.gl/abc12/foo,但由于我不知道您的数据是什么样的,因此您必须确定可接受的边界。

当然,rand(100)只是作为您打算使用的任何功能的占位符。

如果您需要脚本版本,请参阅解压缩代码:

use strict;
use warnings;

BEGIN { $/ = "\n"; $\ = "\n"; }
while (<>) {
    chomp;
    s[http://goo.gl/\w{5}\K\b]['?' . rand(100);]eg;
    print;
}

答案 1 :(得分:1)

你可以用很多语言来做,但在Perl中它非常简单:

#!/usr/bin/perl

use strict;

use constant MAX_RANDOM_STRING_LENGTH => 5;

my $regex_url = '(http://goo.gl/\w{5})';

my @alphanumeric = ("A".."Z", "0".."9");
my $random_cap = $#alphanumeric + 1;

sub generate_string
{
    my $string = "?";
    for (my $i = 0; $i < MAX_RANDOM_STRING_LENGTH; $i++)
    {
        $string .= $alphanumeric[int(rand($random_cap))];
    }
    return $string;
}

my @input = <>;

for(@input)
{   
    my $cur = $_;
    while ($cur =~ /$regex_url/)
    {
        $cur = $';
        my $new_url = $1 . generate_string();       
        s/$1/$new_url/g;
    }
}

print(@input);

用法:

script_name.pl < input.txt > output.txt

答案 2 :(得分:1)

如果每行中的URL不是唯一的,您可以执行以下操作:

#!/usr/bin/perl
use strict;
use warnings;

sub generate {
    my $i = shift;
    return "GeneratedString$i";
}
my $i = 0;
while(my $line = <>) {
    $line =~ s~(http://\S+)~$1 . "?" . &generate($i++)~eg;
    print $line;
}

<强>用法:

test.pl file_to__modify

<强>输出:

http://goo.gl/abc23?GeneratedString1
http://goo.gl/JB007?GeneratedString2

答案 3 :(得分:0)

这可能对您有用:

gs(){  echo $(tr -cd '[:alnum:]' </dev/urandom | head -c5); }
export -f gs
cat <<\! file
> http://goo.gl/abc23
> http://goo.gl/JB007
> bunch of text http://goo.gl/qwert another bunch of text
> another bot http://goo.gl/qwert another bot http://goo.gl/qaza
!
sed '\|http://goo\.gl/[0-9a-zA-Z]\{4,5\}\>|{s//&?'\''$(gs)'\''/g;s/^/echo '\''/;s/$/'\''/}' file |
sh
http://goo.gl/abc23?0Az23
http://goo.gl/JB007?ugczB
bunch of text http://goo.gl/qwert?LDW27 another bunch of text
another bot http://goo.gl/qwert?U9my2 another bot http://goo.gl/qaza?Ybtlp