Use Sed with Ignore Case While Adding Text Before Some Pattern

Use sed with ignore case while adding text before some pattern

You can use the following:

sed 's/[Ff][Ii][Rr][Ss][Tt]/last/g' file

Otherwise, you have the /I and n/i flags:

sed 's/first/last/Ig' file

From man sed:

I

i

The I modifier to regular-expression matching is a GNU extension which
makes sed match regexp in a case-insensitive manner.

Test

$ cat file
first
FiRst
FIRST
fir3st
$ sed 's/[Ff][Ii][Rr][Ss][Tt]/last/g' file
last
last
last
fir3st
$ sed 's/first/last/Ig' file
last
last
last
fir3st

Using sed to delete a case insensitive matched line

For case-insensitive use /I instead of /i.

sed -e "/pattern/Id" filepath

Case-insensitive search and replace with sed

Update: Starting with macOS Big Sur (11.0), sed now does support the I flag for case-insensitive matching, so the command in the question should now work (BSD sed doesn't reporting its version, but you can go by the date at the bottom of the man page, which should be March 27, 2017 or more recent); a simple example:

# BSD sed on macOS Big Sur and above (and GNU sed, the default on Linux)
$ sed 's/ö/@/I' <<<'FÖO'
F@O # `I` matched the uppercase Ö correctly against its lowercase counterpart

Note: I (uppercase) is the documented form of the flag, but i works as well.

Similarly, starting with macOS Big Sur (11.0) awk now is locale-aware (awk --version should report 20200816 or more recent):

# BSD awk on macOS Big Sur and above (and GNU awk, the default on Linux)
$ awk 'tolower($0)' <<<'FÖO'
föo # non-ASCII character Ö was properly lowercased

The following applies to macOS up to Catalina (10.15):

To be clear: On macOS, sed - which is the BSD implementation - does NOT support case-insensitive matching - hard to believe, but true. The formerly accepted answer, which itself shows a GNU sed command, gained that status because of the perl-based solution mentioned in the comments.

To make that Perl solution work with foreign characters as well, via UTF-8, use something like:

perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo"
  • -C turns on UTF-8 support for streams and files, assuming the current locale is UTF-8-based.
  • -Mutf8 tells Perl to interpret the source code as UTF-8 (in this case, the string passed to -pe) - this is the shorter equivalent of the more verbose -e 'use utf8;'.Thanks, Mark Reed

(Note that using awk is not an option either, as awk on macOS (i.e., BWK awk and BSD awk) appears to be completely unaware of locales altogether - its tolower() and toupper() functions ignore foreign characters (and sub() / gsub() don't have case-insensitivity flags to begin with).)


A note on the relationship of sed and awk to the POSIX standard:

BSD sed and awk limit their functionality mostly to what the POSIX sed and
POSIX awk specs mandate, whereas their GNU counterparts implement many more extensions.

Add text between two patterns in File using sed command

Since /r stands for reading in a file, use:

sed '/First/r file1.txt' infile.txt

You can find some info here: Reading in a file with the 'r' command.

Add -i (that is, sed -i '/First/r file1.txt' infile.txt) for in-place edition.

To perform this action no matter the case of the characters, use the I mark as suggested in Use sed with ignore case while adding text before some pattern:

sed 's/first/last/Ig' file

As indicated in comments, the above solution is just printing a given string after a pattern, without taking into consideration the second pattern.

To do so, I'd go for an awk with a flag:

awk -v data="$(<patt_file)" '/First/ {f=1} /Second/ && f {print data; f=0}1' file

Given these files:

$ cat patt_file
This is text to be inserted
$ cat file
Some Text here
First
First
Second
Some Text here
First
Bar

Let's run the command:

$ awk -v data="$(<patt_file)" '/First/ {f=1} /Second/ && f {print data; f=0}1' file
Some Text here
First # <--- no line appended here
First
This is text to be inserted # <--- line appended here
Second
Some Text here
First # <--- no line appended here
Bar

How can i use sed to exclude patterns when joining lines together?

sed '/^1/{/^1\./!N;s/\n/ /}'

If a line does start with a 1, then if it does not start with 1. then append next line. Then replace the newline for a space.

Or just:

sed '/^1\([^\.]\|$\)/N;s/\n/ /'
# same without `\(\|\)`
sed '/^1[^\.]/N;/^1$/N;s/\n/ /'

If a line start with a 1 and then has anything else then a comma or it's the end of line, then append next line. Replace the newline for a space

I only want to join lines that contain '1' (nothing else on the line) with the following line

So just match the 1.

sed '/^1$/N;s/\n/ /'

Maybe you want to just match 1 followed by any whitespace?

sed '/^1[[:space:]]*$/N;s/\n/ /'

Or by spaces only?

sed '/^1 *$/N;s/\n/ /'

The Sed - An Introduction and Tutorial by Bruce Barnett is a great place to learn how to use sed. To learn regexes, I recommend playing with regex crosswords, they let you learn regexes fast and with fun.

How to insert strings containing slashes with sed?

The easiest way would be to use a different delimiter in your search/replace lines, e.g.:

s:?page=one&:pageone:g

You can use any character as a delimiter that's not part of either string. Or, you could escape it with a backslash:

s/\//foo/

Which would replace / with foo. You'd want to use the escaped backslash in cases where you don't know what characters might occur in the replacement strings (if they are shell variables, for example).

Have sed ignore non-matching lines

Another way with plain sed:

sed -e 's/.../.../;t;d'

s/// is a substituion, t without any label conditionally skips all following commands, d deletes line.

No need for perl or grep.

(edited after Nicholas Riley's suggestion)

Remove all lines before a match with sed

try this (GNU sed only):

sed '0,/^bin$/d'

..output is:


$sed '0,/^bin$/d' file
boot
...
sys
tmp
usr
var
vmlinuz

regexp and sed find block of string in multiline block untill it end with space

Using gnu-sed, you can do this:

sed '/^AppServer1/I{:a; /^[[:blank:]]*$/!{s/.*/#&/; n; ba;} }' file

some text here
some text here

#AppServer1:
# name: ${AppServer1.name}
# ip: ${AppServer1.ip}

some text here
some text here

AppServer2:
name: ${AppServer1.name}
ip: ${AppServer1.ip}

some text here
some text here

Details:

  • /^AppServer1/I: Search for AppServer1 case insensitive
  • {: Block start
    • :a: Make label a
    • /^[[:blank:]]*$/! If a line is not a blank line
    • {s/.*/#&/; n; ba;}: Prepend each line with #, read next line and goto label a
  • }: Block end

Using awk you can do this:

awk '/^AppServer1/ {b=1} b && !NF {b=0} b {$0 = "#" $0} 1' file

some text here
some text here

#AppServer1:
# name: ${AppServer1.name}
# ip: ${AppServer1.ip}

some text here
some text here

AppServer2:
name: ${AppServer1.name}
ip: ${AppServer1.ip}

some text here
some text here


Related Topics



Leave a reply



Submit