Bash 用一个标签进行分组
我想使用test.md文件:Bash 用一个标签进行分组,bash,sed,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 到 到目前为止,我想出了这个命令 cat test.md | sed "s/\(.*\):\(TODO\) \(.*\)/\2 \3 file\:/\1/gp" 但是,我得到一个“s的未知选项”错误
/Dropbox/Notes/test.md:TODO something to eat or todo
/Dropbox/Notes/test.md:todo something blue
/Dropbox/Notes/test.md:Todo mixed
到
到目前为止,我想出了这个命令
cat test.md | sed "s/\(.*\):\(TODO\) \(.*\)/\2 \3 file\:/\1/gp"
但是,我得到一个“s的未知选项”错误。此外,我还希望路径描述由一个选项卡分隔
我使用的是GNU sed。如果您想要格式良好的输出,使用
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"
^
(您转义了
:
而不是斜杠。)如果您想要格式良好的输出,使用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"
^
(您转义了
:
而不是斜杠。)您的sed
脚本中的直接问题是,替换文本以及s//
命令中都有斜杠:
sed "s/\(.*\):\(TODO\) \(.*\)/\2 \3 file\:/\1/gp"
^ ^ ^ ^
1 2 3 4
斜杠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'
第一个使用反斜杠来转义作为替换字符串一部分的斜杠(固定代码还为文件://
前缀引入了两个斜杠)。第二个将分隔符从斜杠更改为百分比%
。我会这样做的。我还将整个表达式括在单引号中,这通常更安全—shell不解释单引号中的任何字符。我还对ToDo
进行了匹配,不区分大小写。根据您的sed
中的额外功能,可能还有其他方法可以做到这一点,但它在按图所示编写时仍然有效
我删除了p
限定符,以防止为每个匹配的输入行获得两行输出。如果只需要匹配行,则需要优化操作以:
sed -n -e '/\(.*\):\([Tt][Oo][Dd][Oo]\) \(.*\)/ s%%\2 \3 file\://\1%gp'
现在,模式仅与ToDo行匹配,修改后的版本已写入。您的
sed
脚本中的直接问题是,替换文本以及s///
命令中都有斜杠:
sed "s/\(.*\):\(TODO\) \(.*\)/\2 \3 file\:/\1/gp"
^ ^ ^ ^
1 2 3 4
sed 's|\(.*\):\([tT][oO][dD][oO][^[:space:]]*\)[[:space:]]\(.*\)|\2 \3 file://\1|' YourFile
斜杠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'
第一个使用反斜杠来转义作为替换字符串一部分的斜杠(固定代码还为文件://
前缀引入了两个斜杠)。第二个将分隔符从斜杠更改为百分比%
。我会这样做的。我还将整个表达式括在单引号中,这通常更安全—shell不解释单引号中的任何字符。我还对ToDo
进行了匹配,不区分大小写。根据您的sed
中的额外功能,可能还有其他方法可以做到这一点,但它在按图所示编写时仍然有效
我删除了p
限定符,以防止为每个匹配的输入行获得两行输出。如果只需要匹配行,则需要优化操作以:
sed -n -e '/\(.*\):\([Tt][Oo][Dd][Oo]\) \(.*\)/ s%%\2 \3 file\://\1%gp'
现在,模式只匹配ToDo行,修改后的版本已写入
sed 's|\(.*\):\([tT][oO][dD][oO][^[:space:]]*\)[[:space:]]\(.*\)|\2 \3 file://\1|' YourFile
使用posix版本(-GNU sed上的e),其中没有genreic大写/小写字母模式选项
使用|
作为分隔符,允许在文件:
也可以是(对于此示例结构)
使用posix版本(-GNU sed上的e),其中没有genreic大写/小写字母模式选项
使用|
作为分隔符,允许在文件:
也可以是(对于此示例结构)
您可以将
sed
与不同的分隔符集一起使用,然后通过指定特定的分隔符进行精确打印,将其输送到列
$ 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
分隔符
- 使用捕获组,我们从输入中捕获两部分(文件名和文本)
- 在替换中,我们添加了必要的文本以及分隔符
,
- 此
,
分隔符用于列
,用于分隔两个上下文以进行打印李>
您可以将sed
与不同的分隔符集一起使用,然后通过指定特定的分隔符进行精确打印,将其输送到列
$ 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
分隔符
- 使用捕获组,我们从输入中捕获两部分(文件名和文本)
- 在替换中,我们添加了必要的文本以及分隔符
,
- 此
,
分隔符用于列
,用于分隔两个上下文以进行打印李>
awk
在这种情况下更好。awk
在这种情况下更好。它们都是这样,因为最后的p
没有-n
选项。我承认从问题中复制了太多代码。他们都这样做了,因为最后的p
没有-n
选项。我承认从问题中复制了太多代码。这个输出生成空格作为分隔符。我能把它改成一个真正的制表符吗?@N\u 2如果你有gnu sed,你可以使用sed的| \([^:]*\):\(.*)|\2\t文件:///\1 |'文件
,如果你想要制表符分离,但它作为列输出并不漂亮。请注意,使用此选项,您将不会将其管道化到列
。此输出将生成空格作为分隔符。我可以把它改成一个真正的制表符吗?@N\u 2如果你有gnu sed,你可以使用sed的| \([^:]*\):\(.*)|\2\t文件:///\1 |'文件
如果你想要制表符分离,但它不会像列输出那样漂亮