We want to replace the path on /etc/fstab
file from
/dev/sdb /var/kafka ext4 defaults,noatime 0 0
To ( expected output )
/dev/sdb /var/kafka/hadoop_kafka ext4 defaults,noatime 0 0
The sed syntax that we are wrote is
sed s'/\/var\/kafka/\/var\/kafka\/hadoop_kafka/g' /etc/fstab
so once we run then we get in fstab this
/dev/sdb /var/kafka/hadoop_kafka ext4 defaults,noatime 0 0
But once we run again the sed then we get wrong path in fstab
as:
/dev/sdb /var/kafka/hadoop_kafka/hadoop_kafka ext4 defaults,noatime 0 0
So how to replace the path, only in case we match the path:
/var/kafka
The following 'awk' could assist you here
$ awk '($2=="/var/kafka"){$2="/var/kafka/hadoop_kafka"}1' file
The way awk operates is simple, its syntax, on the other hand, might be a bit unusual for the uninitiated. Awk operates on records, which by default are lines, and each record is spllit in fields. By default these fields are separated by a sequence of one or more blanks (spaces, tabs, ...). Per record, awk will process a sequence of pattern-action pairs written in the form (pattern){action}
. You can read this very simply is If pattern
is true, perform action
. The default pattern is true
and the default action is print
.
When we look at the above we see the following two pattern-action pairs:
($2=="/var/kafka"){$2="/var/kafka/hadoop_kafka"}
. This we can translate as: If the second field equals "/var/kafka", then replace the second field with "/var/kafka/hadoop_kafka"1
: This just says one, which equals to "true" and is a pattern, so we add the default action {print}
. So this statement just prints the current line.With your shown samples/attempts, please try following sed
program.
sed -E 's/^([^ ]*\s+)(\/var\/kafka)(\s.*)/\1\2\/hadoop_kafka\3/ Input_file
Explanation: Firstly using -E
option of sed
to enable ERE(extended regex), then using s
option to perform substitution here. In substitution part regex using back references concept(to keep matched values in a temp buffer memory, to be used later on in program).
^([^ ]*\s+)
: Matching everything from till 1st occurrence of space comes in 1st capturing group. (\/var\/kafka)
: Creating 2nd capturing group which makes sure that it matches /var/kafka
in it. (\s.*)
: Matching rest of the line here. While performing substitution adding \/hadoop_kafka
after 2nd capturing group as per requirement.
NOTE: Above code will print the values on terminal, once you are Happy with results use -i
option to make a inplace save into Input_file.
You may try this sed
:
sed -i.bak -E 's~(^|[[:blank:]])/var/kafka([[:blank:]])~\1/var/kafka/hadoop_kafka\2~g' /etc/fstab
RegEx Details:
(^|[[:blank:]])
: Match start or a space or tab in capture group #1 /var/kafka
: Match text /var/kafka
([[:blank:]])
: Match a space or tab in capture group #2 \1/var/kafka/hadoop_kafka\2
: In replacement put back value captured in group #1 followed by /var/kafka/hadoop_kafka
followed by value captured in group #2 perl -pe's{^\S+\s+/var/kafka\K(?=\s)}{/hadoop_kafka}'
How you'd use it:
perl -i -pe's{^\S+\s+/var/kafka\K(?=\s)}{/hadoop_kafka}' /etc/fstab
You want to replace the second field, which the is between whitespace after the leading sequence of non-whitespace.
s{
^ ( \S+ \s+ ) /var/kafka ( \s | $ )
}{
$1 . "/var/kafka/hadoop_kafka" . $2
}ex
So, you want
perl -pe'
s{
^ ( \S+ \s+ ) /var/kafka ( \s | $ )
}{
$1 . "/var/kafka/hadoop_kafka" . $2
}ex
'
or the equivalent
perl -pe's{^\S+\s+/var/kafka\K(?=\s)}{/hadoop_kafka}'
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.