Atalantia
Atalantia

Reputation: 31

Replace the last character in string

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

Answers (5)

Claes Wikner
Claes Wikner

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

James Brown
James Brown

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 text

Upvotes: 0

Walter A
Walter A

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 sedreplacement string.

echo "${str2}" | tac |sed 's/}[^}]$/&\n\\\\cf2 Its red now/1' |tac

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

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

codeforester
codeforester

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

Related Questions