这个带有许多@符号的“ sed”替换命令如何工作?


8

谁能解释这个sed命令的工作原理?

sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"

3
通常的方法是使用斜杠,但是如果您搜索并用斜杠替换某些内容,则可能会变得很麻烦。这里不是这种情况,因此即使它很好,它也会使像您这样的未来维护者感到困惑。
— 托尔比约恩Ravn的安徒生

2
…并引导他们以sed这种方式学习新知识!:)
— 甜点

Answers:


15

在sed中,替代命令通常写为s/pattern/replacement/options。但是,没有必要使用/-如果方便,您可以使用其他字符,因此可以是s@pattern@replacement@options或s:foo:bar:g。s@+@ @g就像s/+/ /g- +用空格替换所有。同样,s@%@\\x@g全部替换%为\x(单个反斜杠是sed中的转义字符,因此您需要两个反斜杠才能获得实际的反斜杠)。

这样的字符串foo+%2Fbar将变为foo \x2Fbar。printf "%b"将会扩展反斜杠转义的序列,例如\x2F(十六进制值为2F的ASCII字符,即/),最后得到foo /bar。


2
简而言之,URL->文件名解码器。
— 托尔比约恩Ravn的安徒生

10

你问有关对命令解码+ES和%从URL中的序列不只是一个sed命令,这是一个管道是处理输入用sed,然后通过管道将它xargs作进一步处理。首先让我们看一下sed命令:

sed 's@+@ @g;s@%@\\x@g'

您可能更习惯将其视为分隔符/而不是@分隔符,因为/在搜索模式和替换文本中均未出现分隔符,所以在这里可以很容易地做到这一点而不会造成复杂性。此命令等效于:

sed 's/+/ /g;s/%/\\x/g'

就像/,@是的完美标点符号sed。

在输入的每一行上:

  1. s@+@ @g(s/+/ /g)用空格替换(s)的出现+。这会影响+行(g)上的所有es ,而不仅仅是第一个。

  2. ; 结束操作(“命令”),并允许您在同一“脚本”中指定另一个。

  3. s@%@\\x@g(s/%/\\x/g)的替代品(s)的出现%与\x。和以前一样,它作用于所有行,而不仅仅是行首(g)。

    在\\x该\\仅代表一种\因为\具有特殊的意义sed。它的特殊含义实际上是指您用来取代紧随其后的另一个具有特殊含义的字符的特殊含义的字符。因此必须将其转义为\\。


现在让我们来看一个xargs命令,其目的是运行printf。

xargs构造命令行。如果运行,其中是一个或多个单词,则运行时会从其输入中读取其他命令行参数。在这种情况下,由于管道(),to的输入是的输出。通常,将其输入中的任何空格解释为意味着它之前和之后的文本构成单独的参数,但是该选项使它在出现空字符时将参数拆分。xargs command...command...xargscommand...xargssed|xargs-0

在您的命令的预期用途中,将不会显示空字符,并且仅使用一个附加的命令行参数(命令的输出)xargs运行空字符。因此,尽管通常不等效,但在这种情况下,整个管道可能改为使用命令替换而不是这样编写:printf %bsedxargs

printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"

至于什么printf打算在这里做,因为穆鲁说的%b格式说明消耗和打印参数(如%s),但会导致反斜杠逃逸-排序中的sed在管道左侧命令写入生成-要翻译变成他们代表的人物。

假设我运行该命令并http://foldoc.org/debugging%20by%20printf作为输入传递。我得到http://foldoc.org/debugging by printf了输出,因为%20序列被转换为空格。


3

这就是美女sed,适用其范式本身...命令后(如s或tr有或全无),下一个字符被认为是分隔符。

您应该做出明智的选择,以避免干扰外壳程序和命令本身,并使内容可读,但是编写像这样的可怕内容是完全有效的:

echo 'arrival' | sed srarbrg

...并得到brrivbl结果,这就是您所期望的。您可以将其真正变得神秘,例如:

echo 'arrival' | sed s\fa\fb\fg   # \f is form feed, chr(12)

通常的用法是使用斜杠作为定界符,但是当您的表达式包含定界符时,它将更容易掌握意图。您的定界符可以是ASCII8范围内的任何字符(例如多字节定界符£会引发错误)。

请记住,目标是使事情变得更容易,而不是更加神秘。


运行一个神秘的想法,这是一个有效的sed命令,尽管它没有做任何有用的事情:sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
— wjandrea

真好!是的,您也可以将sed命令用作脑筋急转弯,那有多怪异?
— Marabiloso
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.