2

我在尝试在 unix 中过滤以下字符串时遇到问题

<option value="20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg">2012-12-09 13:00h</option>

变成: 20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg2012-12-09 13:00。我可以找到我想要的子字符串的开头,但找不到结尾。

 file=tmpfile
 read -r firstline<$file
 firstArg=$(echo $firstline | sed 's/^.*value="//' | sed 's/">*$//')
 echo $firstArg
 secondArg=$(echo $firstline | sed 's/^.*">//' | sed 's/h<*$//')
 echo $secondArg

输出如下:

20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg">2012-12-09 13:00h</option>
2012-12-09 13:00h</option>

但我真正想要的是

20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg
2012-12-09 13:00
4

2 回答 2

2

次要修复,您.在两个地方丢失(在每行*的第二个之前sed):

 file=tmpfile
 read -r firstline<$file
 firstArg=$(echo $firstline | sed 's/^.*value="//' | sed 's/">.*$//')
 echo $firstArg
 secondArg=$(echo $firstline | sed 's/^.*">//' | sed 's/h<.*$//')
 echo $secondArg

输入:

<option value="20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg">2012-12-09 13:00h</option>

输出:

20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg
2012-12-09 13:00

解释:

  • *匹配前面的字符 0 次或更多次,因此您之前匹配了零个或多个>' 和<'。
  • 匹配.任何字符
  • 所以>.*匹配 . 之后的零个或多个字符>

改进:

此外,这两sed行可以更好地写成:

 firstArg=$(sed 's/^.*value="//;s/">.*$//' <<< "$firstline")
 secondArg=$(sed 's/^.*">//;s/h<.*$//' <<< "$firstline")
  • ;在一个 sed 调用中分隔多个替换模式
  • <<<表示法称为herestring,您可以在此处使用它来保存回声和管道
  • 总是用双引号包裹变量
于 2012-12-09T16:14:14.437 回答
1

尝试这样做:

sed -r 's@.*([0-9]{8}/[^"]+).*>([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}[[:alnum:]]*)<.*@\1\n\2@g'

例子

$ cat file.txt
<option value="20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg">2012-12-09 13:00h</option>
$ sed -r 's@.*([0-9]{8}/[^"]+).*>([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}[[:alnum:]]*)<.*@\1\n\2@g' file.txt
20121209/YvegRascYTGxmWLUIrqW/por121209130030.jpg
2012-12-09 13:00h
于 2012-12-09T16:13:58.493 回答