Insert linefeed in sed (Mac OS X)

前端 未结 9 961
长情又很酷
长情又很酷 2020-11-29 01:36

How do I insert a newline in the replacement part of sed?

This code isn\'t working:

sed \"s/\\(1234\\)/\\n\\1/g\" input.txt > output.txt


        
相关标签:
9条回答
  • 2020-11-29 02:12

    Perl provides a richer "extended" regex syntax which is useful here:

    perl -p -e 's/(?=1234)/\n/g'
    

    means "substitute a newline for the zero-width match following the pattern 1234". This avoids having to capture and repeat part the expression with backreferences.

    0 讨论(0)
  • 2020-11-29 02:14

    Get a GNU sed.

    $ brew install gnu-sed
    

    Then your command will work as expected:

    $ gsed "s/\(1234\)/\n\1/g" input.txt
    test
    1234foo123bar
    1234
    

    nb: you may get GNU sed thanks to mac ports too.

    0 讨论(0)
  • 2020-11-29 02:16

    Here's a single-line solution that works with any POSIX-compatible sed (including the FreeBSD version on macOS), assuming your shell is bash or ksh or zsh:

    sed 's/\(1234\)/\'$'\n''\1/g' <<<'test1234foo123bar1234'
    

    Note that you could use a single ANSI C-quoted string as the entire sed script, sed $'...' <<<, but that would necessitate \-escaping all \ instances (doubling them), which is quite cumbersome and hinders readability, as evidenced by @tovk's answer).

    • $'\n' represents a newline and is an instance of ANSI C quoting, which allows you to create strings with control-character escape sequences.
    • The above splices the ANSI C-quoted string into the sed script as follows:
      • The script is simply broken into 2 single-quoted strings, with the ANSI C-quoted string stuck between the two halves:
      • 's/\(1234\)/\' is the 1st half - note that it ends in \, so as to escape the newline that will be inserted as the next char. (this escaping is necessary to mark the newline as part of the replacement string rather than being interpreted as the end of the command).
      • $'\n' is the ANSI C-quoted representation of a newline character, which the shell expands to an actual newline before passing the script to sed.
      • '\1/g' is the 2nd half.

    Note that this solution works analogously for other control characters, such as $'\t' to represent a tab character.


    Background info:

    • The POSIX sed specification: http://man.cx/sed
      • BSD sed (also used on macOS) stays close to this spec, while GNU sed offers many extensions.
    • A summary of the differences between GNU sed and BSD sed can be found at https://stackoverflow.com/a/24276470/45375
    0 讨论(0)
提交回复
热议问题