Reputation: 31
How can I just replace the last character (it's a }
) from a string? I need everything before the last character but replace the last character with some new string.
I tried many things with awk and sed but didn't succeed.
For example:
...\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural
\\f0
}'
should become:
...\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural
\\f0
\\cf2 Its red now
}'
This replaces the last occurrence of:
}
with
\\cf2 Its red now
}
Upvotes: 1
Views: 3302
Reputation: 1517
awk '{sub(/\\f0/,"\\f0\n\\\\\cfs Its red now")}1' file
...\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural
\\f0
\\cfs Its red now
}'
Upvotes: 0
Reputation: 37464
In awk:
$ awk ' BEGIN { RS=OFS=FS="" } $NF="\\\\cf2 Its red now\n}"' file
RS=""
sets RS
to an empty record (change it to suit your needs)OFS=FS=""
separates characters each to its own field$NF="\\\\cf2 Its red now\n}"
replaces the char in the last field ($NF=}
) with the quoted textUpvotes: 0
Reputation: 20032
First make a string with newlines
str=$(printf "%s\n%s\n%s" '\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural' '\\f0' "}'")
Now you look for the last }
in your string and replace it including a newline.
The $
makes sure it will only replace it at the last line, &
stands for the matches string.
echo "${str}" |sed '$ s/}[^}]$/\\\\cf2 Its red now\n&/'
The above solution only works when the }
is at the last line. It becomes more difficult when you also want to support str2
:
str2=$(printf "Extra } here.\n%s\nsome other text" "${str}")
You can not match the }
on the last line. Removing the address $
for the last line will result in replacing all }
characters (I added a }
at the beginning of str2
). You only want to replace the last one.
Replacing once is forced with ..../1
. Replacing the last and not the first is done by reversing the order of lines with tac
. Since you will tac
again after the replacement, you need to use a different order in your sed
replacement string.
echo "${str2}" | tac |sed 's/}[^}]$/&\n\\\\cf2 Its red now/1' |tac
Upvotes: 0
Reputation: 755094
Replacing the trailing }
could be done like this (with $
as the PS1 prompt and >
as the PS2 prompt):
$ str="...\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural
> \\f0
> }"
$ echo "$str"
...\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural
\f0
}
$ echo "${str%\}}\cf2 It's red now
}"
...\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural
\f0
\cf2 It's red now
}
$
The first 3 lines assign your string to my variable str
. The next 4 lines show what's in the string. The 2 lines:
echo "${str%\}}\cf2 It's red now
}"
contain a (grammar-corrected) substitution of the material you asked for, and the last lines echo the substituted value.
Basically, ${str%tail}
removes the string tail
from the end of $str
; I remember %
ends in 't' for tail (and the analogous ${str#head}
has hash starting with 'h' for head).
See shell parameter expansion in the Bash manual for the remaining details.
If you don't know the last character, you can use a ?
metacharacter to match the end instead:
echo "${str%?}and the extra"
Upvotes: 1
Reputation: 43109
sed would do this:
# replace '}' in the end
echo '\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \f0 }' | sed 's/}$/\\cf2 Its red now}/'
# replace any last character
echo '\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural \f0 }' | sed 's/\(.\)$/\\cf2 Its red now\1/'
Upvotes: 1