16

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/

Douglas Tyding
  • 221
  • 3
  • 9
  • 1
    Possible duplicate of [What delimiters can you use in sed?](https://stackoverflow.com/questions/33914360/what-delimiters-can-you-use-in-sed) – tripleee Jul 29 '19 at 20:42

3 Answers3

10

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

schtever
  • 3,210
  • 16
  • 25
  • 2
    It should also be noted that this isn't a `sed` specific convention, but is also supported by Perl and other languages that let you specify the regex delimiter. – Ryan J Jan 27 '15 at 00:28
6

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>.

Community
  • 1
  • 1
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
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(.)()('
NeronLeVelu
  • 9,908
  • 1
  • 23
  • 43