Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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
Bash 找到模式(YYYY-MM-DD)并将其替换为相同的值,并用撇号连接_Bash_Shell_Sed_Nsregularexpression - Fatal编程技术网

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,但方式有点不同,干杯。