我正在分析一个批处理文件,并且有一行可以编辑文本文件(输入)并生成一个txt文件(输出)。
批处理使用三个帮助工具:grep
,sed
和cut
。我试着阅读他们的手册,但这并不容易。
该行是:
type input.txt | sed "s#""#'#g" | grep -o "class='name[^>]*" | sed -n "/id=/p" | grep -o "surname=[^>]*" | cut -d"'" -f2 >output.txt
我想知道这条线是如何解释的?规则是什么?有更聪明的方法吗(例如使用一个工具而不是全部三个工具)?
答案 0 :(得分:4)
我会添加到jeb的答案中,尽管它涵盖了你提出的大部分内容。
这三个命令是从Linux移植的模拟命令,它们执行以下操作:
sed
:用于过滤和转换文本的流编辑器。grep
:用于打印与图案匹配的线条的工具。cut
:用于剪切文件每一行的选定部分的工具。我建议您通过在Linux中键入man <command name>
或在Google上搜索相同的字符串(例如,“man grep”)来阅读有关这三个命令的更多信息。
另外,查看regular expressions。虽然初学者通常不清楚它们,但它们是表现模式的常用且紧凑的方式。
关于问题中的具体用法:
sed "s#""#'#g"
对于每一行,这将使用撇号(""
)替换任何引号('
)。
grep -o "class='name[^>]*"
这仅打印以class='name
开头但没有跟随>
的部分行。
sed -n "/id=/p"
默认情况下,Sed打印每一行。另一方面,sed -n "<some pattern> /p"
仅打印与指定模式匹配的行。在这种情况下,Sed仅打印包含id=
的行。
grep -o "surname=[^>]*"
这仅打印以surname=name'
开头但没有跟随>
的行部分。
cut -d"'" -f2
将每行解析为由撇号('
)分隔的连续字段,然后选择第二行。
一切都是管道,这意味着每个命令的输出都作为右边下一个命令的输入。 “input.txt”的内容被送入Sed命令,然后输出到grep命令,依此类推。显然,最终输出会打印到名为“output.txt”的新文件中。
是的,就像杰布提到的那样,这看起来像是一个尴尬的解决方案,因为这里的所有内容都可以单独完成sed
,大概只需要一两个命令。
答案 1 :(得分:2)
这或多或少都很容易。
将其拆分为单个命令:
sed "s#""#'#g"
相当于sed "s/""/'/g"
,它将用'
字符替换每个引号。
grep -o "class='name[^>]*"
将只捕获带有文本class='name
的行,而-o
开关应在输出前加STDIN:
(不知道为什么这应该有用) 。
sed -n "/id=/p"
只会捕获包含文字id=
的行。
grep -o "surname=[^>]*"
将仅捕获包含文字surname=
的行。
cut -d"'" -f2
会将该行划分为多个部分,这些部分由'
(-d'
)分隔,您获得第二个字段(-f2
)
是的,这看起来像是一个快速的黑客解决方案,这可以通过sed单独解决
特别是当单个文本的顺序处于固定顺序时,例如:
<class="name17" id=13> <surname=Frank>
答案 2 :(得分:0)
| character是管道符。它用于将一个命令的输出传递给另一个命令的输入。
&gt; character是重定向字符。它将标准输出重定向到文件。
因此,在您的示例中,该过程以 type 命令开始:
type input.txt
这会将 input.txt 发送到标准输出,然后通过管道传输到下一个命令的输入中:
sed "s#""#'#g"
等等通过其他管道 grep 和 sed 命令。
最终 cut 命令使用&gt;字符将其输出重定向到 output.txt 文件。
cut -d"'" -f2 >output.txt