简体   繁体   English

如何使用变量来搜索和替换使用sed或awk?

[英]How to use variable to search and replace using sed or awk?

I am trying to find and replace a value using variable with the help of sed and awk but not getting any output - 我试图在sed和awk的帮助下使用变量找到并替换值,但没有得到任何输出 -

#cat temp.txt
this is Testing of date : 2016-11-25 07:20:10

It is printing the variable but not working in gsub function - 它正在打印变量但在gsub函数中不起作用 -

awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{print srch,repl}' temp.txt
2016-11-25 07:20:10 [25/Nov/16:07:20:10]

I tried below awk command - 我试过下面的awk命令 -

awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{gsub("srch","repl",$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub(srch,repl,$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub("$srch","$repl",$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub(srch,repl,$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{print gsub(srch,repl,$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub("srch","repl",$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub("$srch","$repl",$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub("$srch","$repl",$0)}' temp.txt
awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub(srch,repl,$0)}' temp.txt

#var1="2016-11-25 07:20:10"
#var2="[25/Nov/16:07:20:10]"
#echo $var1 $var4
2011-11-25 07:20:10 [25/Nov/11:07:20:10]
#awk -v srch="$var1" -v repl="$var4" '{ gsub(srch,repl,$0)}' temp.txt

With sed command - 使用sed命令 -

#echo $var1 $var4
2011-11-25 07:20:10 [25/Nov/11:07:20:10]
sed 's/"$var1"/"$var4"/' temp.txt
sed 's/$var1/'"${var4}"'/' temp.txt
sed 's|$var1|'"${var4}"'|' temp.txt
sed 's/\$var1/${var4}/' temp.txt
sed 's/\$var1/$var4/' temp.txt
sed "s/"$var1"/"$var4"/" temp.txt
sed 's/'$var1'/'$var4'/' temp.txt
sed 's/'$var1'/'$var4\/' temp.txt
sed -e "s/${var1}/${var4}/' temp.txt
sed -e "s/${var1}/${var4}/" temp.txt
sed "s/$var1/$var4/" temp.txt
sed 's/'"$var1"'/'"$var4"'/' temp.txt
sed 's/'"$var1"'/'$var4'/' temp.txt

Not sure what i am missing. 不知道我错过了什么。

Expected output - 预期产量 -

#this is Testing of date : [25/Nov/11:07:20:10]

this one works, but you need to add print or nothing will be printed: 这个工作,但你需要添加print或什么都不会打印:

awk -v srch="2016-11-25 07:20:10" -v repl="[25/Nov/16:07:20:10]" '{ gsub(srch,repl,$0); print}' temp.txt

result: 结果:

this is Testing of date : [25/Nov/16:07:20:10]

with sed you can do it as well (as long as you use double quotes, or variables won't be evaluated), but since replacement string contains slashes, you have to change sed expression delimiter or you get a sed parsing error, I chose # 使用sed你也可以这样做(只要你使用双引号,或者不会评估变量),但由于替换字符串包含斜杠,你必须更改sed表达式分隔符或者你得到一个sed解析错误,我选择了#

$ var1="2016-11-25 07:20:10"; var4="[25/Nov/11:07:20:10]"
$ sed "s#$var1#$var4#" temp.txt

result: 结果:

this is Testing of date : [25/Nov/11:07:20:10]

It would be: 这将是:

var1="2016-11-25 07:20:10"
var2="[25/Nov/16:07:20:10]"
awk -v srch="$var1" -v repl="$var2" '{gsub(srch,repl)} 1' temp.txt
sed 's#'"$var1"'#'"$var2"'#g' temp.txt

You should also read Is it possible to escape regex metacharacters reliably with sed as the above would fail if var1 contained RE metacharacters or var2 contained backreferences. 您还应该阅读是否可以使用sed可靠地转义正则表达式元字符,因为如果var1包含RE元字符或var2包含反向引用,则上述操作将失败。

At a bit of a tangent - I would tackle it in perl and parse your date. 有点切线 - 我会用perl解决它并解析你的约会。 (I know you didn't ask about perl , but I think it's a good fit for this - it's installed in most of the places you have sed or awk available) (我知道你没有问过perl ,但我认为它非常适合这个 - 它安装在大多数你可以使用sedawk的地方)

It would work a bit like this: 它会有点像这样:

#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece; 

#iterate __DATA__ special filehandle
while ( <DATA> ) {
    #extract time via regex
    my ( $time_str ) = m/([\d\-]+\s+[\d\:]+)$/; 
    next unless $time_str;
    #parse it into a Time::Piece object
    my $timestamp = Time::Piece -> strptime ("$time_str", "%Y-%m-%d %H:%M:%S");    
    #print it using a new format string
    my $new_time_str = $timestamp -> strftime("%d/%b/%y:%H:%M:%S");
    #replace old with new in line
    s/$time_str/\[$new_time_str\]/;
    #print current line
    print;
}

__DATA__
this is Testing of date : 2016-11-25 07:20:10

And for the sake of a command line solution, that condenses into: 并且为了命令行解决方案,它凝聚成:

perl -pe '($ts)=m/([\d\-]+\s+[\d\:]+)$/;s{$ts}{Time::Piece->strptime($ts,"%Y-%m-%d %H:%M:%S")->strftime("[%d/%b/%y:%H:%M:%S]")}e;' 

You can pipe into this, or specify a filename as an argument, just like you would with sed or awk . 您可以管道,或指定文件名作为参数,就像使用sedawk

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM