简体   繁体   中英

Adding a line using sed

Can't seem to find the right way to do this, despite checking my regex in a reg checker.

Given a text file containing, amongst others, this entry:

zone    "example.net"    {
        type master;
        file "/etc/bind/zones/db.example.net";
        allow-transfer { x.x.x.x;y.y.y.y; };
        also-notify { x.x.x.x;y.y.y.y; };
};

I want to add lines after the also-notify line, for that domain specifically.

So using this sed command string:

sed '/"example\.net".*?also-notify.*?};/a\nxxxxxxx/s' named.conf.local

I thought should work to add 'xxxxxxx' after the line. But nope. What am I doing wrong?

Following awk may help on this.

awk -v new_lines="new_line here" '/also-notify/{flag=1;print new_lines} /^};/{flag=""} !flag'  Input_file

In case you want to edit Input_file itself then append > temp_file && mv temp_file Input_file to above code too. Also print new_lines here new_lines is a variable you could print the new liens directly too in there.

With POSIX sed, you can use the a for append command with an escaped literal new line:

$ sed  '/^[[:blank:]]*also-notify/ a\
NEW LINE' file

With GNU sed, a is slightly more natural since the new line is assumed:

$ gsed  '/^[[:blank:]]*also-notify/ a NEW LINE' file

The issue with the sed in your example is two fold.

The first is any sed regex cannot be for a multi-line match as in example\\.net".*?also-notify.*? . That is more of a perl type match. You would need to use a range operator for the start as in:

$ sed  '/"example\.net/,/also-notify/{
       /^[[:blank:]]*also-notify/ a\
    NEW LINE 
    }' file

The second issue is the \\n in the appended text. With POSIX sed, the \\n is not supported in any context. With GNU sed, the new line is assumed and the \\n is out of context (if immediately after the a ) and interpreted as an escaped literal n . You can use \\n with GNU sed after 1 character but not immediately after. In POSIX sed, leading spaces of the appended line will always be stripped.

You're pretty close already. Just use a range ( /pattern/,/pattern/{ #commands } ) to select the text you want to operate on and then use /pattern/a/\\ ... to add the line you want.

/"example\.net"/,/also-notify/{
/also-notify/a\
\        this is the text I want to add.
}

sed trims leading space on text to be appended. Adding a backslash \\ at the start of the line prevents this.

In Bash, this would look like something like:

sed -e '/"example\.net"/,/also-notify/{
  /also-notify/a\
  \        this is the text I want to add.
  }' named.conf.local

Also note that sed uses an older dialect of regular expressions that doesn't support non-greedy quantifies like *? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM