For example: I have string1 = 'abcd'
, and string2 = 'xwyz'
.
I want to replace the 3rd character of string1 ('c') with the 4th character of string2 ('z').
Of course, string indexing starts from 0.
How can I accomplish this?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityWith bash substring manipulation:
s1="abcd"
s2="xwyz"
s1=${s1:0:2}${s2:3}${s1:3}
${s1:0:2}
- the 1st slice containing ab
(till the 3rd character c
)
${s2:3}
- the 4th character of the s2
string to be inserted
${s1:3}
- the last (4th) character of the s1
string
Final s1
value:
echo $s1
abzd
Or with GNU awk tool:
gawk -v s2=$s2 -v FPAT='[a-z]' '{$3=substr(s2,4)}1' OFS="" <<< $s1
abzd
<<< $s1
- the first string s1
is considered as input content
-v s2=$s2
- passing the second string s2
as a variable into awk script
FPAT='[a-z]'
- regex pattern defining a field value ([a-z]
- any alphabetic character)
Alternatively, you could also apply the "empty" field separator FS=""
treating each character as separate field:
gawk -v s2=$s2 'BEGIN{ FS=OFS="" }{$3=substr(s2,4)}1' <<< $s1
abzd
sc2
which would be ${s2:2:1}
although they then proceed to use the 4th in the example. In any case it would be more suitable to slice exactly 1 character and not the entire trailing string since there's not explicit length limit of 4. Otherwise +1.
Jul 20, 2017 at 12:41
-F ''
if you want each character to be a field. The space is necessary for some versions of awk.
Jul 20, 2017 at 13:10
Here is awk code (long and complicated, but work for me)
echo |awk -v a="$string1" -v b="$string2" '{split(a,a1,""); n=split(b,b1,"");a1[2]=b1[3];for (i=1;i<=n;i++) {printf a1[i]}}'
BEGIN
block. Maybe it's fine here but personally I'd always quote those variables too.
Jul 20, 2017 at 12:52