【问题标题】:Unix shell scripting — find and replaceUnix shell 脚本——查找和替换
【发布时间】:2016-03-18 20:48:34
【问题描述】:

有多个文件(1000 个文件)需要此更改;手动操作是不可行的——谁能建议如何在 Unix/Linux shell 脚本中进行操作?

要求:

  1. CONF_CATALOG_MULTI_SERVER_HOST_SECONDARY 和 CONF_SEARCH_MULTI_SERVER_HOST_SECONDARY 有l2cache[25-48] 的地方,我需要更改[13-24]

    示例:edc-v1-l2cache25 这将更改为 edc-v1-l2cache13edc-v1-l2cache26 更改为 edc-v1-l2cache14,依此类推,直到 36 更改为 24 并删除其余的 37-48。

  2. CONF_SEARCH_MULTI_SERVER_HOST 和 CONF_CATALOG_MULTI_SERVER_HOST 哪里有l2cache[1-24],我需要改成[1-12] 即需要删除l2cache[13-24],只有edc-v1-l2cache[1-12] 应该存在于CONF_CATALOG_MULTI_SERVER_HOST 和CONF_SEARCH_MULTI_SERVER_HOST 中

示例/输入数据:

CONF_CATALOG_MULTI_SERVER_HOST_SECONDARY=edc-v1-l2cache25 ,edc-v1-l2cache26 ,edc-v1-l2cache27 ,edc-v1-l2cache28 ,edc-v1-l2cache29 ,edc-v1-l2cache30 ,edc-v1-l2cache31 ,edc-v1-l2cache32 ,edc-v1-l2cache33 ,edc-v1-l2cache34 ,edc-v1-l2cache35 ,edc-v1-l2cache36 ,edc-v1-l2cache37 ,edc-v1-l2cache38 ,edc-v1-l2cache39 ,edc-v1-l2cache40 ,edc-v1-l2cache41 ,edc-v1-l2cache42 ,edc-v1-l2cache43 ,edc-v1-l2cache44 ,edc-v1-l2cache45 ,edc-v1-l2cache46 ,edc-v1-l2cache47 ,edc-v1-l2cache48 
CONF_SEARCH_MULTI_SERVER_HOST_SECONDARY=edc-v1-l2cache25 ,edc-v1-l2cache26 ,edc-v1-l2cache27 ,edc-v1-l2cache28 ,edc-v1-l2cache29 ,edc-v1-l2cache30 ,edc-v1-l2cache31 ,edc-v1-l2cache32 ,edc-v1-l2cache33 ,edc-v1-l2cache34 ,edc-v1-l2cache35 ,edc-v1-l2cache36 ,edc-v1-l2cache37 ,edc-v1-l2cache38 ,edc-v1-l2cache39 ,edc-v1-l2cache40 ,edc-v1-l2cache41 ,edc-v1-l2cache42 ,edc-v1-l2cache43 ,edc-v1-l2cache44 ,edc-v1-l2cache45 ,edc-v1-l2cache46 ,edc-v1-l2cache47 ,edc-v1-l2cache48 
CONF_CATALOG_MULTI_SERVER_HOST=edc-v1-l2cache1 ,edc-v1-l2cache2 ,edc-v1-l2cache3 ,edc-v1-l2cache4 ,edc-v1-l2cache5 ,edc-v1-l2cache6 ,edc-v1-l2cache7 ,edc-v1-l2cache8 ,edc-v1-l2cache9 ,edc-v1-l2cache10 ,edc-v1-l2cache11 ,edc-v1-l2cache12 ,edc-v1-l2cache13 ,edc-v1-l2cache14 ,edc-v1-l2cache15 ,edc-v1-l2cache16 ,edc-v1-l2cache17 ,edc-v1-l2cache18 ,edc-v1-l2cache19 ,edc-v1-l2cache20 ,edc-v1-l2cache21 ,edc-v1-l2cache22 ,edc-v1-l2cache23 ,edc-v1-l2cache24 
CONF_SEARCH_MULTI_SERVER_HOST=edc-v1-l2cache1 ,edc-v1-l2cache2 ,edc-v1-l2cache3 ,edc-v1-l2cache4 ,edc-v1-l2cache5 ,edc-v1-l2cache6 ,edc-v1-l2cache7 ,edc-v1-l2cache8 ,edc-v1-l2cache9 ,edc-v1-l2cache10 ,edc-v1-l2cache11 ,edc-v1-l2cache12 ,edc-v1-l2cache13 ,edc-v1-l2cache14 ,edc-v1-l2cache15 ,edc-v1-l2cache16 ,edc-v1-l2cache17 ,edc-v1-l2cache18 ,edc-v1-l2cache19 ,edc-v1-l2cache20 ,edc-v1-l2cache21 ,edc-v1-l2cache22 ,edc-v1-l2cache23 ,edc-v1-l2cache24 

输出数据:

CONF_CATALOG_MULTI_SERVER_HOST_SECONDARY=edc-v1-l2cache13 ,edc-v1-l2cache14 ,edc-v1-l2cache15 ,edc-v1-l2cache16 ,edc-v1-l2cache17 ,edc-v1-l2cache18 ,edc-v1-l2cache19 ,edc-v1-l2cache20 ,edc-v1-l2cache21 ,edc-v1-l2cache22 ,edc-v1-l2cache23 ,edc-v1-l2cache24  
CONF_SEARCH_MULTI_SERVER_HOST_SECONDARY=edc-v1-l2cache13 ,edc-v1-l2cache14 ,edc-v1-l2cache15 ,edc-v1-l2cache16 ,edc-v1-l2cache17 ,edc-v1-l2cache18 ,edc-v1-l2cache19 ,edc-v1-l2cache20 ,edc-v1-l2cache21 ,edc-v1-l2cache22 ,edc-v1-l2cache23 ,edc-v1-l2cache24 
CONF_CATALOG_MULTI_SERVER_HOST=edc-v1-l2cache1 ,edc-v1-l2cache2 ,edc-v1-l2cache3 ,edc-v1-l2cache4 ,edc-v1-l2cache5 ,edc-v1-l2cache6 ,edc-v1-l2cache7 ,edc-v1-l2cache8 ,edc-v1-l2cache9 ,edc-v1-l2cache10 ,edc-v1-l2cache11 ,edc-v1-l2cache12  
CONF_SEARCH_MULTI_SERVER_HOST=edc-v1-l2cache1 ,edc-v1-l2cache2 ,edc-v1-l2cache3 ,edc-v1-l2cache4 ,edc-v1-l2cache5 ,edc-v1-l2cache6 ,edc-v1-l2cache7 ,edc-v1-l2cache8 ,edc-v1-l2cache9 ,edc-v1-l2cache10 ,edc-v1-l2cache11 ,edc-v1-l2cache12 

【问题讨论】:

  • perl -pe 's/cache([0-9]+)/cache . ( $1 - 12 )/ge if m/CONF_CATALOG_MULTI/' 为您提供大部分的帮助。如果您努力重新格式化问题以使其易于阅读,那么有人可能愿意提供更多帮助。上面的 perl 可以很容易地包装在一个循环中,该循环将适用于所有必要的 inpu 文件,您可以添加一个 -i 选项来更改文件。祝你好运!
  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。你试过什么,你在哪里遇到麻烦?此外,虽然您显示了一些示例输入数据,但您没有显示所需的输出——这总是有帮助的。另外,您说“CSMSH CCMSH”,但没有任何数据行同时具有这两种功能;你的意思是“或”而不是“和”?
  • 对于项目符号 1,您应该如何将 25-48 范围内的 24 个值压缩成 13-24 范围内的 12 个值?

标签: regex shell unix scripting


【解决方案1】:

所以,这些名字太长了!

从输出来看,对于 CSMSHS 和 CCMSHS 条目,您需要进行更改,以便重新组织具有 25-48 的条目,以便有 12 个值为 13-24 的条目,并删除其他 12 个条目。

同样,对于 CSMSH 和 CCMSH 条目,您希望删除值为 13-24 的条目。

大概您不必担心文件中的不稳定条目;他们现在都是一致的,以后也应该是一致的。

坦率地说,最简单的事情是创建替换字符串并使用相对简单的搜索来识别需要更改的行(确保更改是幂等的;将脚本重新应用到转换后的文件不会更改文件第二次)。我发现空格逗号符号令人反感;在我工作的圈子里,应该是逗号。但是,我们可以不用管它。

我会使用 Perl,但如果您愿意,也可以使用 Awk,而 Python 也可以轻松完成这项工作。

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

my $base = "edc-v1-l2cache";
my $secondary = "";
my $pad = "";
for (my $i = 13; $i <= 24; $i++)
{
     $secondary .= $pad . $base . $i;
     $pad = " ,";   # ", "!
}
my $primary = "";
$pad = "";
for (my $i = 1; $i <= 12; $i++)
{
     $primary .= $pad . $base . $i;
     $pad = " ,";   # ", "!
}

while (<>)
{
    s//$1$secondary/
        if (m/(CONF_(?:CATALOG|SEARCH)_MULTI_SERVER_HOST_SECONDARY=)${base}25 ,.*${base}48$/);
    s//$1$primary/
        if (m/(CONF_(?:CATALOG|SEARCH)_MULTI_SERVER_HOST=)${base}1 ,.*${base}24$/);
    print;
}

如果某些条目可能丢失并且需要特殊处理,则您必须更加努力。

【讨论】:

  • 感谢乔纳森,实际上想要在 bash shellscript 环境中,不过真的很感谢你的努力。
  • 那是一个可以被 Bash 运行的脚本。如果您想在 Bash 中执行此操作,请将循环音译并改为应用 sed。或者使用 awk 代替 Perl。如果你不能使用除了 Bash 之外的任何东西(所以即使 sed 不在了),那么你已经被分配了一个crackpot 任务。 Perl 一个用于 Bash 脚本的工具,就像 sedawk 一样。
  • 是的,awk 和 sed 都可以使用,我是脚本初学者,这只是我的工具包
  • 如果没有正式的约束“你不能使用 Perl”,那么就使用 Perl。如果有一个正式的约束“你不能用 Perl 进行编辑”,你能用 Perl 生成sed 脚本吗?基本上,如果您不为此使用 Perl 或 Python(或 Ruby,或……),那么您就是在往自己的道路上扔石头。可以在 awk 中完成;在 awk 中编写代码会很痛苦。可以通过 Bash 创建 sed 脚​​本来完成;编写代码也会很痛苦。做 Perl 已经够糟糕的了。我要睡觉了;您必须希望其他人能够帮助您克服障碍。
  • 感谢乔纳森的帮助