문제

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

도움이 되었습니까?

해결책

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 ;.

다른 팁

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.

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@'
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.

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.

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top