Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex AWK:将变量用作正则表达式的一部分_Regex_Bash_Shell_Awk - Fatal编程技术网

Regex AWK:将变量用作正则表达式的一部分

Regex AWK:将变量用作正则表达式的一部分,regex,bash,shell,awk,Regex,Bash,Shell,Awk,我有一个与此类似的文本文件,其中包含用户名、说明和两个时间范围值,采用德语日期格式: User###@###Description###@###1. August - 8. August 2016###@###1. September - 7. September 2016 每个字段都使用###@###分隔符分隔。我想检查某个字段(例如$3)是否包含两个相同的月份名称。如果此指定字段中有两个月的名称,则应删除第一个月的名称,以便awk的输出为: User###@###Description##

我有一个与此类似的文本文件,其中包含用户名、说明和两个时间范围值,采用德语日期格式:

User###@###Description###@###1. August - 8. August 2016###@###1. September - 7. September 2016
每个字段都使用
###@###
分隔符分隔。我想检查某个字段(例如$3)是否包含两个相同的月份名称。如果此指定字段中有两个月的名称,则应删除第一个月的名称,以便awk的输出为:

User###@###Description###@###1. - 8. August 2016###@###1. - 7. September 2016
然后我想到为我的bash脚本(使用awk命令)创建一个for循环,它递增
I
,以便从预定义变量中读取月份名称。在这里,您可以获得更详细的外观

script.sh:

m1=January; m2=February; m3=March; m4=April; m5=May; m6=June; m7=July; m8=August; m9=September; m10=October; m11=November; m12=December


    awk -F '###@###' '
    {for (i=1;i++;i<=12){ 
    count=0;
    $3 ~ 'm'i {count++};
    if (count == 2){gsub(mi,"" ,$3)}
    }}' Info.txt > Info.tmp 
m1=一月;m2=二月;m3=三月;m4=四月;m5=五月;m6=六月;m7=7月;m8=八月;m9=九月;m10=10月;m11=11月;m12=12月
awk-F'####@####''

{for(i=1;i++;i您可以将预定义的名称放入awk脚本中。可能是这样的。(快速黑客-即将注销一天;)

编辑:为方便未来读者,以下是OP的shortText.com链接:

awk-F'####@####'' 开始{m1=“一月”;m2=“二月”;m3=“三月”;m4=四月;m5=五月;m6=六月;m7=七月;m8=八月;m9=九月;m10=十月;m11=十一月;m12=十二月} {for(i以m为单位){ 计数=0; $3~(m[i]“*”m[i]){print++count}; 如果(count==1){sub(m[i],“”,$3)} }}'Info.txt>Info.tmp


下面是如何将bash变量设置为awk的方法。最好使用一个月数组,然后检查月是否存在。`“m”i`似乎不是一个好方法。请在谷歌上搜索它,并阅读Arnold Robbins的《有效的awk编程》第四版,开始学习如何使用awk。@an和m的“i”我对应于月号,其中包含月名。我知道您提供的解决方案,并在之前尝试过,但它没有解释如何在使用“i”调用变量时处理变量。“mi”,“m'i”和/mi/只是我尝试过的几件事。我已经有了“-v m1=m1 m2=m2…”作为其中的一个选项,但我在本例中删除了它,以防我做错了什么。@EdMorton在本例中的特殊之处是,它有一个for循环,其中“I”是bash变量的一部分。因此它不是重复的。不,这在两个不同的方面是错误的。@xcw我尝试了您的解决方案,但您非常简化了脚本。在您的代码中,您检查$3中是否有m[I]。但实际上,我需要知道是否有>两个<相同的m[I],以便可以从文本文件中删除第一个月的名称。我认为您的方法可能有效,但m[I]应该被类似/m[I]*m[I]的正则表达式替换/……这是我目前的问题。我不知道如何在正则表达式中调用变量。你知道吗?@OtakuKyon我明白你的意思。我投票重新开始这个问题,但如果其他人不同意,我建议单独开始一个问题,只包含
awk
部分,而不是
bash
部分。类似这样的问题“如何在awk中折叠字段中的重复文本?”但目前,对于变量,
$1~(m[0]”*“m[0])
将测试字段1是否两次出现
m[0]
在其中。您可以使用字符串作为正则表达式。我在脚本中实现了您的正则表达式,但它告诉我有语法错误。当我将其放入if查询时,什么也没有发生。之后我将` count++´修改为` print++count´,以便检查计数器是否递增。但它没有。看起来像这个正则表达式x不工作。(编辑:我写了‘$3~(m[I]”“*”m[I])',这样这个正则表达式就可以与我的文本文件兼容。)你可以在这里检查当前的脚本:@OtakuKyon数组初始化看起来像是问题-所有12个都应该像
m[1]=“Januar”
,带有方括号(
m[1]
,而不是
m1
)和双引号(
“Januar”
,而不是
Januar
)。如果您仍然有问题,请发布另一个问题,因为注释不够长,无法进行有效调试:)。
awk -F ... ' BEGIN { m[1]="January"; m[2]="February"; ... } 
            {for(i=1...
             if ( $3 ~ m[i] ) { count++ }
             ...}'