【问题标题】:How to append a RANDOM string to all occurrences of another string in file如何将随机字符串附加到文件中所有出现的另一个字符串
【发布时间】:2012-03-02 02:12:55
【问题描述】:

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

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

我想做的是将一个字符串附加到所有 url。我设法(在用户Dan Fego 的帮助下)使用 sed 完成了这项工作,但它只能通过附加一个静态字符串来工作。

我正在寻找一种将不同的字符串附加到每次出现的方法。假设我有一个函数generatestring,它每次都回显一个不同的字符串。我想将不同的生成字符串附加到每个 url。 http://goo.gl/abc23 将变为 http://goo.gl/abc23?GeneratedString1http://goo.gl/JB007 将变为 http://goo.gl/JB007?GeneratedString2 等等。

有人知道这是否可以做到吗?有人告诉我 perl 是要走的路,但我对 perl 的经验为零。这就是我在这里问的原因。

提前感谢您的帮助。

【问题讨论】:

  • 字符串是如何生成的?它们是匹配网址的功能吗?还是别的什么?
  • 不,它们只是随机的 5 个字符的字母数字字符串。

标签: regex string perl bash


【解决方案1】:

ETA:假设 URL 嵌入在其他文本中:

$ 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(&lt;&gt;) 循环,这基本上意味着它从参数文件名或从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;
}

【讨论】:

  • 哇,@TLP 第一行在我看来真的像一些随机字符放在一起。 :) 我还不习惯。 :) 如何使用 m0skit0 的 generate_string 函数为您的单行生成随机后缀?
  • @zigamilek 如果您想添加该长度的子例程,我建议您改为使用我答案底部的代码将其设为脚本。
【解决方案2】:

如果每行中的 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

【讨论】:

  • 这个其实很接近我需要的。是否可以对其进行修改以利用所有 url 格式相同的事实http://goo.gl/*****(末尾有 5 个字母数字字符)。因为有些链接没有空格分隔。
  • 好的,成功了。我用(http://goo.gl/\w{5}) 替换了(http://\S+)。这是正确的方法吗?我错过了什么吗?
【解决方案3】:

你可以用很多语言做到这一点,但在 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

【讨论】:

  • 没问题,反正使用 Perl 很容易。给你。
  • 感谢您的回答。但是,它不能满足我的需要。我想我之前还不够清楚。链接出现在文本中。例如:等等等等,goo.gl/abc23,随机随机,goo.gl/JB007。它们不会每行出现一个,并且文件不只包含链接。
  • 那么 URL 的格式是什么?任何 URL 编译字符串?我如何知道 URL 何时结束?它们被什么东西划定了吗?
  • s/$/generate_string()/e, print for &lt;&gt; 更紧凑一些。您还想忘记您对chop 的所有了解,转而使用chomp
  • TY 关于印章。但是我不喜欢压缩东西,Perl 已经足够神秘,让它变得更加神秘......
【解决方案4】:

这可能对你有用:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 2021-09-30
    • 2016-02-07
    • 1970-01-01
    • 2017-06-06
    相关资源
    最近更新 更多