我有大量具有不同日期和时间的文本,因此我不能将其用作模式,我在想是否可以搜索第一个,
和打印后"
,并搜索第二个,
和打印前"
。它应该看起来像这样:
4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222
现在看起来:
4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222
预先非常感谢您。
答案1
一种非常简单的方法是替换第一个和第二个逗号,如您所说:
sed 's/,/,"/;s/,/",/2' infile
除非您想匹配日期(假设所有行的格式相同):
sed 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\ [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)/"&"/' infile
或第一个和第二个逗号之间的所有内容:
sed 's/^\([^,]*,\)\([^,]*\)\(,.*\)/\1"\2"\3/' infile
答案2
您说您想要引用日期/时间字段?
awk 'BEGIN {FS=OFS=","} $2="\""$2"\""' infile > outfile
答案3
其他方式:
sed 's/,\([^,]*\),/,"\1",/' <infile >outfile
这在没有至少两个逗号的任何行上都不起作用 - 因此它将完全跳过任何没有至少两个逗号的行。它总是只会得到前两个出现的逗号 - 因为基本的正则表达式模式是基于最左边最长规则 - 也就是说匹配总是按照很快尽可能并尽可能长的尽可能。换句话说,在一行中找到的第一个逗号将满足我们搜索的第一个逗号,而下一个逗号将始终紧跟在它们之间最长的非逗号字符序列之后。
sed 's/,\([^,]*\),/,"\1",/
' <<\IN
4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222
IN
它匹配第一个逗号,后跟[^,]*
零个或多个非逗号*
字符,再紧跟一个逗号。它将非逗号匹配分组到子表达式中,并反向引用第一个[^
,]*
\(
\)
\1
(仅限此处)替换语句右侧替换字段中的匹配组s///
。逗号被直接替换为逗号,"
和引号以及引号",
和逗号,但反向引用组会替换自身。所以...
输出
4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222
或者你可以做...
sed '/,.*,/s/[^,]*/"&"/2' <infile >outfile
这使得s///
替换成为有条件的 - 因为此处使用的替换可能适用于仅匹配一个逗号的行 - 在这种情况下,它将引用除该逗号之外的所有内容。为了确保替换仅适用于匹配至少两个逗号的行,我们显式地/,.*,/
仅处理匹配至少一个逗号后跟零个或多个*
.
任何类型的字符以及至少一个逗号的行,然后仅在这些行上行我们是否s///
用 2cd 匹配来替换[^,]*
零个或多个*
非逗号,其自身被您的引号&
包围。"
即使一行中的第一个字符是逗号,它仍然会得到正确的字段,例如:
sed '/,.*,/s/[^,]*/"&"/2' <<\IN
,2014-05-05 10:01:24,1238461,1,222
IN
...打印...
,"2014-05-05 10:01:24",1238461,1,222
...因为零个或多个非逗号字符的第一个匹配是第一个逗号之前出现的零长度字符串。
答案4
这是一个sed
方法:
$ sed -n 's/\(\([0-9]\|-\)* \([0-9]\|:\)*\)/\"\1\"/p' file.txt
4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222
这也可以工作:
sed -n 's/\(.* \([0-9]\|:\)*\)/\"\1\"/p' file.txt