我有这种数据:
1,1990-01-01,2,A,2015-02-09
1,NULL,2,A,2015-02-09
1,1990-01-01,2,A,NULL
并寻找解决方案,该解决方案将用旧值替换文件中的每个日期,但添加撇号。该示例的基本预期结果将是:
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01',2,A,NULL
我已经找到了一种方法来找到与我的日期相匹配的模式,但是仍然无法找到可以替换的模式。
sed 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/????/' a.txt > b.txt
答案 0 :(得分:1)
通过用括号()
括起来来将日期分组。然后,您可以将此捕获的组与\1
一起使用(第二个组为\2
等。)
sed "s/\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\)/'\1'/g"
请注意末尾的g
,以确保替换所有匹配项(如果一行中有多个匹配项)。
如果将-r
开关添加到sed,则可以省略()
之前的笨拙的反斜杠:
sed -r "s/([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])/'\1'/g"
这可以使用量词进一步简化:
sed -r "s/([0-9]{4}-[0-9]{2}-[0-9]{2})/'\1'/g"
甚至:
sed -r "s/([0-9]{4}-([0-9]{2}){2})/'\1'/g"
如评论中所述:此外,在这种特殊情况下,可以使用&
代替\1
,它匹配整个查找表达式,并省略()
:
sed -r "s/[0-9]{4}(-[0-9]{2}){2}/'&'/g"
答案 1 :(得分:1)
您需要使用捕获组,并用g
标志替换 all 个匹配项。
sed 's/\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\)/'"'"'\1'"'"'/g' a.txt > b.txt
替换文本有点令人困惑,因为shell中的单引号字符串不能包含单引号,因此您必须关闭单引号字符串,然后使用双引号单引号。在$'...'
中使用bash
样式的引号会稍微简化一点,但需要转义反斜杠。
sed $'s/\\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\\)/\'\1\'/g' a.txt > b.txt
或者,您可以直接对脚本加双引号,因为其中目前没有任何内容可以扩展:
sed "s/\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\)/'\1'/g" a.txt > b.txt
还有一种特殊的&
替换文本,它可以扩展到正则表达式匹配的内容,因此可以避免使用显式捕获组:
sed "s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/'&'/g" a.txt > b.txt
答案 2 :(得分:0)
这是awk中的一个:
$ awk -v q="'" '
BEGIN { FS=OFS="," } # set selimiters
{
for(i=1;i<=NF;i++) # loop all fields
if($i~/[0-9]{4}-[0-9]{2}-[0-9]{2}/) # if field has a date looking string
$i=q $i q # quote it
}1' file
输出:
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01',2,A,NULL
答案 3 :(得分:0)
请您尝试以下操作。(match
中提到的REGEX也可以写为[0-9]{4}-[0-9]{2}-[0-9]{2}
,但是由于我的awk
是旧版本,因此无法对其进行测试,因此您可以尝试一次)
awk -v s1="'" '
{
while(match($0,/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/)){
val=val substr($0,1,RSTART-1) s1 substr($0,RSTART,RLENGTH) s1
$0=substr($0,RSTART+RLENGTH)
}
print val
val=""
}' Input_file
输出如下。
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01'
答案 4 :(得分:0)
使用GNU sed:
sed -E 's/([0-9]{2,4}-?){3}/'\''&'\''/g' file
根据文件内容的不同,日期也可能描述为1
或2
,后跟九个破折号或数字的组合:
sed -E 's/[12][-0-9]{9}/'\''&'\''/g" file
答案 5 :(得分:0)
使用Perl,这很简单
perl -pe ' s/(\d{4}-\d\d-\d\d)/\x27$1\x27/g '
带输入-\ x27用于单引号
$ cat liubo.txt
1,1990-01-01,2,A,2015-02-09
1,NULL,2,A,2015-02-09
1,1990-01-01,2,A,NULL
$ perl -pe ' s/(\d{4}-\d\d-\d\d)/\x27$1\x27/g ' liubo.txt
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01',2,A,NULL
$
如果要使用单引号,请转义$并将命令包装在双引号中
$ perl -pe " s/(\d{4}-\d\d-\d\d)/\'\$1\'/g " liubo.txt
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01',2,A,NULL
$