nav_jan
nav_jan

Reputation: 2553

insert a string at specific position in a file by SED awk

I have a string which i need to insert at a specific position in a file :

The file contains multiple semicolons(;) i need to insert the string just before the last ";"

Is this possible with SED ?

Please do post the explanation with the command as I am new to shell scripting

before :

adad;sfs;sdfsf;fsdfs

string = jjjjj

after

adad;sfs;sdfsf jjjjj;fsdfs

Thanks in advance

Upvotes: 0

Views: 7645

Answers (6)

anubhava
anubhava

Reputation: 785128

Something like this may work for you:

echo "adad;sfs;sdfsf;fsdfs"| awk 'BEGIN{FS=OFS=";"} {$(NF-1)=$(NF-1) " jjjjj"; print}'

OUTPUT:

adad;sfs;sdfsf jjjjj;fsdfs

Explanation: awk starts with setting FS (field separator) and OFS (output field separator) as semi colon ;. NF in awk stands for number of fields. $(NF-1) thus means last-1 field. In this awk command {$(NF-1)=$(NF-1) " jjjjj" I am just appending jjjjj to last-1 field.

Upvotes: 0

potong
potong

Reputation: 58391

This might work for you:

echo 'adad;sfs;sdfsf;fsdfs'| sed 's/\(.*\);/\1 jjjjj;/'
adad;sfs;sdfsf jjjjj;fsdfs

The \(.*\) is greedy and swallows the whole line, the ; makes the regexp backtrack to the last ;. The \(.*\) make s a back reference \1. Put all together in the RHS of the s command means insert jjjjj before the last ;.

Upvotes: 3

Jens
Jens

Reputation: 72639

sed -e 's/\(;[^;]*\)$/ jjjj\1/'

Inserts jjjj before the part where a semicolon is followed by any number of non-semicolons ([^;]*) at the end of the line $. \1 is called a backreference and contains the characters matched between \( and \).

UPDATE: Since the sample input has no longer a ";" at the end.

Upvotes: 0

Gilles Quénot
Gilles Quénot

Reputation: 185053

For now, the shorter solution using sed : =)

sed -r 's@;([^;]+);$@; jjjjj;\1@' <<< 'adad;sfs;sdfsf;fsdfs;'
  • -r option stands for extented Regexp
  • @ is the delimiter, the known / separator can be substituted to any other character
  • we match what's finishing by anything that's not a ; with the ; final one, $ mean end of the line
  • the last part from my explanation is captured with ()
  • finally, we substitute the matching part by adding "; jjjj" ans concatenate it with the captured part

Edit: POSIX version (more portable) :

echo 'adad;sfs;sdfsf;fsdfs;' | sed 's@;\([^;]\+\);$@; jjjjj;\1@'

Upvotes: 1

user unknown
user unknown

Reputation: 36229

echo 'adad;sfs;sdfsf;fsdfs;' | sed -r 's/(.*);(.*);/\1 jjjj;\2;/'

You don't need the negation of ; because sed is by default greedy, and will pick as much characters as it can.

Upvotes: 0

Lev Levitsky
Lev Levitsky

Reputation: 65791

sed 's/\([^;]*\)\(;[^;]*;$\)/\1jjjjj\2/' filename

(substitute jjjjj with what you need to insert).

Example:

$ echo 'adad;sfs;sdfsf;fsdfs;' | sed 's/\([^;]*\)\(;[^;]*;$\)/\1jjjjj\2/'
adad;sfs;sdfsfjjjjj;fsdfs;

Explanation:

sed finds the following pattern: \([^;]*\)\(;[^;]*;$\). Escaped round brackets (\(, \)) form numbered groups so we can refer to them later as \1 and \2.

[^;]* is "everything but ;, repeated any number of times.

$ means end of the line.

Then it changes it to \1jjjjj\2.

\1 and \2 are groups matched in first and second round brackets.

Upvotes: 1

Related Questions