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 forAppServer1
case insensitive{
: Block start:a
: Make labela
/^[[:blank:]]*$/!
If a line is not a blank line{s/.*/#&/; n; ba;}
: Prepend each line with#
, read next line and goto labela
}
: 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
How to Make Binary Distribution of Qt Application for Linux
How to Display Only Files from Aws S3 Ls Command
Pytorch Says That Cuda Is Not Available
Getting Current Path in Variable and Using It
Set Environment Variable with Space in Linux
Is It Necessary to Deregister a Socket from Epoll Before Closing It
How Bash Handles the Jobs When Logout
Why Is Pr_Debug of the Linux Kernel Not Giving Any Output
Using Named Pipes with Bash - Problem with Data Loss
Svn: Ignoring an Already Committed File
Filtering Rows Based on Number of Columns with Awk
What Is the Purpose of Features.H Header
What Does "|" Mean in a Terminal Command Line
Force Gnu Linker to Generate 32 Bit Elf Executables
Sed to Insert on First Match Only
Executing Script on Receiving Incoming Connection with Xinetd