Why does sed command contain at symbols

2020-08-17 07:14发布

问题:

I don't understand why the following sed command contains an @ symbol:

sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

I've looked at /etc/pam.d/sshd for the before/after effects of this command:

BEFORE:

...
# Set the loginuid process attribute.
session    required     pam_loginuid.so
...

AFTER:

...
# Set the loginuid process attribute.
session optional pam_loginuid.so
....

Is the @ symbol possibly part of regex or sed syntax? Could not find any doco on this.

Note: The above sed command is actually part of a Dockerfile RUN command in tutorial: https://docs.docker.com/examples/running_ssh_service/

回答1:

These are alternate delimiters for the regular expressions and replacement string. Handy when your regex or replacement string includes '/'.



回答2:

From the sed manual

The syntax of the s (as in substitute) command is ‘s/regexp/replacement/flags’. The / characters may be uniformly replaced by any other single character within any given s command. The / character (or whatever other character is used in its stead) can appear in the regexp or replacement only if it is preceded by a \ character.

From the POSIX specification:

[2addr]s/BRE/replacement/flags

Substitute the replacement string for instances of the BRE in the pattern space. Any character other than <backslash> or <newline> can be used instead of a to delimit the BRE and the replacement. Within the BRE and the replacement, the BRE delimiter itself can be used as a literal character if it is preceded by a <backslash>.



回答3:

as other says, it is another delimiter than traditionnal / in the s///action. This is usually used when / is found/part of the pattern like searching (or replacing by) a unix path that need to escape the /

s/\/my\/path/\/Your\/path/
# same as
s@my/path@/Your/path@

You often use a character that is not alpha numeric (but you can). The only (logical) constraint is to avoid a special character (aka special meaning like ^$[]{}()+\*.) for regex that make it difficult to read (but functionnal) and without the feature of this character in the pattern

echo "b(a)l" | sed 's(.)()('


标签: sed