Bash 找到模式(YYYY-MM-DD)并将其替换为相同的值,并用撇号连接
我有这样的数据:Bash 找到模式(YYYY-MM-DD)并将其替换为相同的值,并用撇号连接,bash,shell,sed,nsregularexpression,Bash,Shell,Sed,Nsregularexpression,我有这样的数据: 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
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
通过用括号括住模式来捕捉组中的日期
()
。然后您可以将此捕获组与\1
(第二组是\2
等)一起使用
注意末尾的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
,后者匹配整个查找表达式,并省略()
:
通过用括号括住模式来捕捉组中的日期
()
。然后您可以将此捕获组与\1
(第二组是\2
等)一起使用
注意末尾的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
,后者匹配整个查找表达式,并省略()
:
以下是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
以下是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
您需要使用捕获组,并使用
g
标志替换所有匹配的出现
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
您需要使用捕获组,并使用
g
标志替换所有匹配的出现
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
请您尝试以下内容。(在
match
中提到的REGEX可以写成[0-9]{4}-[0-9]{2}-[0-9]{2}
但由于我的awk
是旧版本,所以无法测试,您可以尝试一次)
输出如下
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01'
请您尝试以下内容。(在
match
中提到的REGEX可以写成[0-9]{4}-[0-9]{2}-[0-9]{2}
但由于我的awk
是旧版本,所以无法测试,您可以尝试一次)
输出如下
1,'1990-01-01',2,A,'2015-02-09'
1,NULL,2,A,'2015-02-09'
1,'1990-01-01'
使用GNU时:
sed -E 's/([0-9]{2,4}-?){3}/'\''&'\''/g' file
根据您的文件内容,日期也可以描述为1
或2
,后跟九个破折号或数字的组合:
sed -E 's/[12][-0-9]{9}/'\''&'\''/g" file
使用GNU时:
sed -E 's/([0-9]{2,4}-?){3}/'\''&'\''/g' file
根据您的文件内容,日期也可以描述为1
或2
,后跟九个破折号或数字的组合:
sed -E 's/[12][-0-9]{9}/'\''&'\''/g" file
使用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
$
使用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
$
你可以1。写
[0-9]{4}
而不是[0-9][0-9][0-9][0-9]
。2.使用&
而不是\1
,这样你就不必使用(…)
。你可以压缩更多的[0-9]{4}(-0-9]{2}{2}
@karakfa谢谢。非常感谢你的帮助!!!我差不多是这样尝试smth的,但是对shell中的regexp没有很好的理解((你可以1.写[0-9]{4}
而不是[0-9][0-9][0-9][0-9][0-9][0-9][0-9]
。2.用&
而不是\1
,这样你就不必使用(…)
。你可以压缩更多的[0-9]{4(-0-9][2}{2}
@karakfa谢谢。非常感谢您的帮助!!!我尝试了差不多这样的smth,但对shell中的regexp不是很了解((像您的先生一样,我也使用了match,但方式有点不同,干杯。像您的先生一样,我也使用了match,但方式有点不同,干杯。