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
해결책
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.