Reputation: 2315
I have a log where i want to apply a replace just inside a regexp match text.
Example, take this log line:
date machine text random text and yet more random text - status code
i want o replace the all spaces by a _ inside the text area, without replacing all other spaces in the log. the output would be this:
date machine text_random_text_and_yet_more_random_text - status code
To match the area i want to replace i have this regexp:
/machine \(.*\) - /
As the text is not standard, i can have one space to 20, so its hard to match it directly, so i match the start and the end of the substring.
Trying to use it i tried this:
sed `/machine \(.*\) - / s/ /_/g ' logfile
but of course, it will replace all spaces in the log, not just the matched substring.
I managed to do it with awk, by iterating and printing each field until i find the machine
, where i change the OFS="_"
and restore it to space when i find the -
. It works... yet, i was curious if this is possible to solve using sed.
Thanks
Upvotes: 2
Views: 491
Reputation: 41446
Since there are two space before text you like to have with underscore and space - space after, you can do like this:
awk -F " | - " '/machine/ {gsub(/ /,"_",$2)}1' file
date machine text_random_text_and_yet_more_random_text status code
Upvotes: 1
Reputation: 246744
Perl:
echo "date machine text random text and yet more random text - status code" |
perl -pe 's/(?<=machine )(.*)(?= - )/ ($repl = $1) =~ s{\s}{_}g; $repl /e'
date machine text_random_text_and_yet_more_random_text - status code
Upvotes: 0
Reputation: 58351
This might work for you (GNU sed):
sed -r 's/(\S+\s+){2}/&\n/;s/\s+-/\n&/;h;y/ /_/;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/' file
Upvotes: 1
Reputation: 51593
Another awk solution might be:
awk '{
# Capture the stringpart in `a`rray
match($0,"machine (.*) -",a)
# Make the changes
gsub(" ","_",a[1])
print gensub("machine (.*) -","machine " a[1] " -","g")
}' INPUTFILE
Upvotes: 0
Reputation: 784908
Here is one gnu-awk command to solve this:
s='date machine text random text and yet more random text - status code'
awk '{gsub(/ /, "_", $2); print $1 " machine " $2 " - " $3}' FS='machine *| *- *' <<<"$s"
date machine text_random_text_and_yet_more_random_text - status code
Upvotes: 0