使用选项卡进行Sed分组

时间:2014-05-05 06:18:06

标签: bash sed

我想发送test.md文件:

/Dropbox/Notes/test.md:TODO something to eat or todo
/Dropbox/Notes/test.md:todo something blue
/Dropbox/Notes/test.md:Todo mixed

TODO something to eat or todo    file:///Dropbox/Notes/test.md
todo something blue              file:///Dropbox/Notes/test.md
Todo mixed                       file:///Dropbox/Notes/test.md

到目前为止,我想出了这个命令

cat test.md | sed  "s/\(.*\):\(TODO\) \(.*\)/\2 \3    file\:/\1/gp"

但是,我收到“s的未知选项”错误。此外,我还希望路径描述由TAB界定。

我正在使用GNU sed。

4 个答案:

答案 0 :(得分:2)

如果您想要格式良好的输出,使用awk

可能会更容易
awk -F: '{printf "%-40sfile://%s\n", $2, $1}' inputfile

-40指定第一个字段的宽度为40个字符,左对齐。 s表示它是一个字符串。

为了您的输入,它会产生:

TODO something to eat or todo           file:///Dropbox/Notes/test.md
todo something blue                     file:///Dropbox/Notes/test.md
Todo mixed                              file:///Dropbox/Notes/test.md

您的sed表达式无法正常工作,因为您在替换中有一个未转义的/

sed  "s/\(.*\):\(TODO\) \(.*\)/\2 \3    file:\/\1/gp"
                                              ^

(您逃脱了:而不是斜线。)

答案 1 :(得分:2)

sed脚本中的直接问题是替换文本和s///命令中都有斜杠:

sed  "s/\(.*\):\(TODO\) \(.*\)/\2 \3    file\:/\1/gp"
       ^                      ^               ^  ^
       1                      2               3  4

Slash 3就是这里的闯入者。您可以通过几种不同的方式解决它:

sed -e 's/\(.*\):\([Tt][Oo][Dd][Oo]\) \(.*\)/\2 \3    file\:\/\/\1/g'
sed -e 's%\(.*\):\([Tt][Oo][Dd][Oo]\) \(.*\)%\2 \3    file\://\1%g'

第一个使用反斜杠来转义作为替换字符串一部分的斜杠(固定代码还为file://前缀引入了两个斜杠)。第二个将分隔符从斜杠更改为百分比%。这就是我这样做的方式。我还将整个表达式用单引号括起来,这通常更安全 - shell不会解释单引号内的任何字符。我还对ToDo不区分大小写的匹配进行了匹配。根据{{​​1}}中的额外设施,可能还有其他方法可以执行此操作,但如果按照显示进行编写,则可以正常工作。

我删除了sed限定符,以防止您为每个匹配的输入行获得两行输出。如果您只想要匹配的行,那么您需要将操作细化为:

p

现在该模式仅匹配ToDo行,并且编写了修改后的版本。

答案 2 :(得分:1)

您可以将sed与不同的分隔符集一起使用,然后通过为漂亮打印指定特定分隔符将其传递给column

$ sed 's|\([^:]*\):\(.*\)|\2,file:///\1|' file | column -ts','
TODO something to eat or todo  file:////Dropbox/Notes/test.md
todo something blue            file:////Dropbox/Notes/test.md
Todo mixed                     file:////Dropbox/Notes/test.md
  • 我们使用|作为我们的sed分隔符
  • 使用捕获组,我们从输入中捕获两个部分(文件名和文本)
  • 在我们的替换中,我们添加了必要的文本以及分隔符,
  • ,分隔符用于column分隔两个上下文以进行漂亮打印。

答案 3 :(得分:0)

sed 's|\(.*\):\([tT][oO][dD][oO][^[:space:]]*\)[[:space:]]\(.*\)|\2 \3 file://\1|' YourFile

使用posix版本(GNU sed上的-e),其中没有genreic capital / small letter pattern的选项 使用|作为分隔符,以便在/

之后使用简单的file:

也可以(对于此样本结构)

sed 's|\([^:]*\):\(.*\)|\2 file://\1|' YourFile