Linux 根据映射对字符串进行更改

Linux 根据映射对字符串进行更改,linux,bash,shell,awk,sed,Linux,Bash,Shell,Awk,Sed,我有以下字符串格式 str="aaa.[any_1].bbb.[any_2].ccc" 我有以下映射 地图1: map2 考虑到上面的映射,在str上执行的最佳命令是什么 $ command $str aaa.1.bbb.1.ccc 将map文件转换为sed脚本: sed 's%^%s/%;s% ==> %/%;s%$%/g%' map? 将结果脚本应用于输入字符串。您可以通过流程替换直接执行此操作: sed 's%^%s/%;s% ==> %/%;s%$%/g%' map?

我有以下字符串格式

str="aaa.[any_1].bbb.[any_2].ccc"
我有以下映射

地图1:

map2

考虑到上面的映射,在
str
上执行的最佳命令是什么

$ command $str
aaa.1.bbb.1.ccc

map
文件转换为
sed
脚本:

 sed 's%^%s/%;s% ==> %/%;s%$%/g%' map?
将结果脚本应用于输入字符串。您可以通过流程替换直接执行此操作:

sed 's%^%s/%;s% ==> %/%;s%$%/g%' map? | sed -f- <(echo "$str")
更新:我现在认为我没有正确理解这个问题,因此我的解决方案是错误的。我把它留在这里是因为我不知道这个答案的一部分是否对你的问题有帮助,但我鼓励你先看看其他答案

不知道你的意思。但有件事:

any_1="1"
any_2="2"
str="aaa.${any_1}.bbb.${any_2}.ccc"
echo $str
花括号告诉解释器变量名的结束位置和正常字符串的恢复位置。结果:

aaa.1.bbb.2.ccc
您可以循环此操作:

for any_1 in {1..2}; do
    for any_2 in {1..3}; do
        echo aaa.${any_1}.bbb.${any_2}.ccc
    done
done
这里,
{1..3}
表示数字1、2和3。结果

aaa.1.bbb.1.ccc
aaa.1.bbb.2.ccc
aaa.1.bbb.3.ccc
aaa.2.bbb.1.ccc
aaa.2.bbb.2.ccc
aaa.2.bbb.3.ccc
  • 您可以使用多个映射,但不限于2个(偶数和find to cat找到的每个映射)
  • 基于别名和值在内部没有空间这一事实(如果有,可以调整)

我对@chw21的答案投了赞成票,因为它为问题场景提供了正确的工具。但是,

您可以根据以下内容设计基于
perl
的命令

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

my $text = join '',<DATA>;
my %myMap = (
 'any_1' => '1',
 'any_2' => '2'
);

$text =~s/\[([^]]+)\]/replace($1)/ge;

print $text;

sub replace {
 my ($needle) = @_;
 return "\[$needle\]" if ! exists $myMap{ lc $needle};
 return $myMap{lc $needle};
}

__DATA__
aaa.[any_1].bbb.[any_2].ccc
#/usr/bin/perl
严格使用;
使用警告;
我的$text=加入“”,;
我的%myMap=(
'any_1'=>'1',
'any_2'=>'2'
);
$text=~s/\[([^]+)\]/替换($1)/ge;
打印$text;
子替换{
我的($针)=@;
如果!存在$myMap{lc$needle},则返回“\[$needle\]”;
返回$myMap{lc$needle};
}
__资料__
aaa.[any_1].bbb.[any_2].ccc
唯一需要解释的可能是正则表达式,它匹配方括号之间的文本,并将文本发送到替换例程。在replace例程中,我们从对应于其参数的映射中获取映射值。

$cat tst.awk
$ cat tst.awk
BEGIN {
    FS=OFS="."
    m["any_1"]=1; m["cny_1"]=2
    m["any_2"]=1; m["bny_2"]=2; m["cny_2"]=3
    for (i in m) map["["i"]"] = m[i]
}
{
    for (i=1;i<=NF;i++) {
        $i = ($i in map ? map[$i] : $i)
    }
    print
}
$ awk -f tst.awk <<<'aaa.[any_1].bbb.[any_2].ccc'
aaa.1.bbb.1.ccc
开始{ FS=OFS=“” m[“任意1”]=1;m[“人民币1”]=2 m[“任意2”]=1;m[“任意2”]=2;m[“人民币2”]=3 对于(m中的i)map[“[“i”]”]=m[i] } {
对于(i=1;iWhy the loop?有两个不同键的地图(any、bny、cny),我看不出这在任何方面如何适用于这个问题。
aaa.1.bbb.1.ccc
aaa.1.bbb.2.ccc
aaa.1.bbb.3.ccc
aaa.2.bbb.1.ccc
aaa.2.bbb.2.ccc
aaa.2.bbb.3.ccc
{
 echo "${str}"
 cat Map1
 cat Map2
} | sed -n '1h;1!H;$!d
x
s/[[:space:]]*==>[[:space:]]*/ /g
:a
s/\[\([^]]*\)\]\(.*\)\n\1 \([^[:cntrl:]]*\)/\3\2/
ta
s/\n.*//p'
#!/usr/bin/perl
use strict;
use warnings;

my $text = join '',<DATA>;
my %myMap = (
 'any_1' => '1',
 'any_2' => '2'
);

$text =~s/\[([^]]+)\]/replace($1)/ge;

print $text;

sub replace {
 my ($needle) = @_;
 return "\[$needle\]" if ! exists $myMap{ lc $needle};
 return $myMap{lc $needle};
}

__DATA__
aaa.[any_1].bbb.[any_2].ccc
$ cat tst.awk
BEGIN {
    FS=OFS="."
    m["any_1"]=1; m["cny_1"]=2
    m["any_2"]=1; m["bny_2"]=2; m["cny_2"]=3
    for (i in m) map["["i"]"] = m[i]
}
{
    for (i=1;i<=NF;i++) {
        $i = ($i in map ? map[$i] : $i)
    }
    print
}
$ awk -f tst.awk <<<'aaa.[any_1].bbb.[any_2].ccc'
aaa.1.bbb.1.ccc