将包含时间戳的shell变量传递给SED

时间:2014-01-05 14:46:43

标签: shell unix sed

我有一个文件( problem.txt),其中每行以时间戳开头,格式为: 2014-01-05 00:00:49,908

problem.txt内容:

2014-01-05 00:00:49,004 ABCDE DEF Sample1 THE END   
2014-01-05 00:00:51,037 ABCDE DEF Sample2 THE END   
2014-01-05 01:01:00,911 ABCDE DEF Sample3 THE END   
2014-01-05 01:30:49,747 ABCDE DEF sample4 THE END   
2014-01-05 02:00:00,475 ABCDE DEF sample5 THE END   
2014-01-05 03:00:00,037 ABCDE DEF sample6 THE END 

手头的任务是找到给定时间戳之间的所有行,其中开始和结束时间戳存储在shell变量中( $ searchstart0,$ searchend0 )。

例如:

searchstart0=2014-01-05 00:00:49,004   
searchend0=2014-01-05 03:00:00,037

此外,结果必须存储在文本文件( results.txt )中。 所以,我使用sed命令来执行上述任务。以下是命令

sed -n "/$searchstart0/ , /$searchend0/p" problem.txt > /home/abc/results.txt

但是,在执行上述commnad时,生成的文本文件为空,我看到以下消息:

sed -e expression #1, char 0:no previous regular expression

此外,我尝试使用单引号而不是双引号执行命令,但仍然生成的文件为空。 如果有任何可能的解决方案来完成任务,请告诉我。

3 个答案:

答案 0 :(得分:1)

sed来电没有问题 也许你没有正确设置这两个变量。请确保将值括在引号之间,因为文本中有空格(例如searchstart0="2014-01-05 00:00:51,037"),然后重试。

答案 1 :(得分:1)

问题是searchstart0searchend0 为空

$ searchstart0=2014-01-05 00:00:49,004  
-bash: 00:00:49,004: command not found
$ searchend0=2014-01-05 03:00:00,037
-bash: 03:00:00,037: command not found
$ echo $searchstart0 | wc -c
   1
$ echo $searchend0 | wc -c
   1

由于分配中的错误,没有为这些变量分配。因此,有效地,在评估变量之后,sed执行如下:

$ sed -n "// , //p" sample.txt
sed: -e expression #1, char 0: no previous regular expression

第一个模式为空时引发此错误消息。第二个被允许为空,但是它不会做你想要的,就像使用$作为结束模式一样,打印从开始模式到文件结尾的所有内容。

如果你修复了变量赋值,那么你的脚本应该可以工作:

searchstart0='2014-01-05 00:00:49,004'
searchend0='2014-01-05 03:00:00,037'

顺便说一下,,表达式中sed周围不需要空格,你可以像这样写:

sed -n "/$searchstart0/,/$searchend0/p" problem.txt > /home/abc/results.txt

答案 2 :(得分:0)

如果shell变量设置正确,则给定代码应该可以正常处理样本数据,因为引用的时间戳都出现在数据文件中:

searchstart0="2014-01-05 00:00:49,004"
searchend0="2014-01-05 03:00:00,037"
sed -n -e "/$searchstart0/,/$searchend0/p" problem.txt

输出:

2014-01-05 00:00:49,004 ABCDE DEF Sample1 THE END
2014-01-05 00:00:51,037 ABCDE DEF Sample2 THE END
2014-01-05 01:01:00,911 ABCDE DEF Sample3 THE END
2014-01-05 01:30:49,747 ABCDE DEF sample4 THE END
2014-01-05 02:00:00,475 ABCDE DEF sample5 THE END
2014-01-05 03:00:00,037 ABCDE DEF sample6 THE END

但是,如果请求是针对2014-01-05 00:00:00,000和2014-01-05 02:00:00,000之间的时间戳,则sed将无法打印任何数据。您可以使用以下代码awk进行处理:

searchstart0="2014-01-05 00:00:00,000"
searchend0="2014-01-05 02:00:00,000"
awk "\$0 >= \"$searchstart0\" && \$0 < \"$searchend0\" { print }" problem.txt

或者,没有反斜杠:

awk -v s0="$searchstart0" -v e0="$searchend0" '$0 >= s0 && $0 < e0 { print }' problem.txt

输出:

2014-01-05 00:00:49,004 ABCDE DEF Sample1 THE END
2014-01-05 00:00:51,037 ABCDE DEF Sample2 THE END
2014-01-05 01:01:00,911 ABCDE DEF Sample3 THE END
2014-01-05 01:30:49,747 ABCDE DEF sample4 THE END

这取决于行开头的时间戳;如果时间戳位于数据文件的第5列和第6列中,则必须更加努力工作。

严格来说,{ print }可以省略; awk将其作为模式的默认操作。我更喜欢明确。