I want to extract a string from a line in a text file between two different characters:
for example:
:string"
I want to extract string. It has to be done in a one-liner.
I want to extract a string from a line in a text file between two different characters:
for example:
:string"
I want to extract string. It has to be done in a one-liner.
One way:
$ cat file
abc:string"def
$ sed -e 's/\(^.*:\)\(.*\)\(".*$\)/\2/' file
string
$
echo ":string\"" | awk -F":" '{print $2}' | awk -F"\"" '{print $1}'
Another one:
sed 's/.*:\(.*\)".*/\1/' file
Regards
Hi.
With perl:
cat <<'EOF' |
Characters before :string" and characters after.
EOF
perl -wn -e 'print "$1\n" if m{[:](.*?)["]};'
Producing:
string
cheers, drl
Do you need to handle multiple matches on one line?
Awk:
awk '$0=$2' FS=: RS=\"
Or:
perl -nle'print $1 while /:(.*?)\"/g'
Hi.
The point raised by radoulov is a good one. Not all of the solutions produce the same results because of different assumptions:
#!/bin/bash -
# @(#) s3 Demonstrate comparison of solutions.
echo
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version =o $(_eat $0 $1) awk perl sed
cat <<'EOF' >data1
Characters before :string" and characters after, :another instance".
EOF
echo
echo " Input file data1:"
cat data1
echo
echo " Results of perl, left-most, shortest extraction:"
perl -wn -e 'print "$1\n" if m{[:](.*?)["]};' data1
echo
echo " Results of perl, longest extraction:"
perl -wn -e 'print "$1\n" if m{[:](.*)["]};' data1
echo
echo " Results of one sed solution:"
sed -e 's/\(^.*:\)\(.*\)\(".*$\)/\2/' data1
echo
echo " Results of another sed solution:"
sed 's/.*:\(.*\)".*/\1/' data1
echo
echo " Results of one awk solution:"
awk '$0=$2' FS=: RS=\" data1
echo
echo " Results of perl, all extractions (if -> while;g):"
perl -wn -e 'print "$1\n" while m{[:](.*?)["]}g;' data1
exit 0
Producing:
% ./s3
(Versions displayed with local utility "version")
Linux 2.6.11-x1
GNU bash 2.05b.0
GNU Awk 3.1.4
perl 5.8.4
GNU sed version 4.1.2
Input file data1:
Characters before :string" and characters after, :another instance".
Results of perl, left-most, shortest extraction:
string
Results of perl, longest extraction:
string" and characters after, :another instance
Results of one sed solution:
another instance
Results of another sed solution:
another instance
Results of one awk solution:
string
another instance
Results of perl, all extractions (if -> while;g):
string
another instance
Which is another lesson for me in the usefulness of complete, non-ambiguous requirements ... cheers, drl
I need to handle the following line:
192.168.0.0 - - [07/May/2008:11:42:31 +0100] "GET /images/top_line.gif HTTP/1.1" 200 51 "https://server.com/caches/themes/html/styles/All.css" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14 WHE_SLS" "sbslang=; www-stats=11984687e55.1dd9a88; PD_STATEFUL_d796f17c-15c0-11dd-bb1e-c0a8580aaa77=%2Fwas; JSESSIONID=0000sSm-zPjR_Wd9ZG4yYwMBx7U:12cgh2sq9; sbsmwwindowlist.AGY=%5B%5B%2269848949%22%2C%220%22%2C%22default%22%2C%220%22%2C%221%22%2C%2207114231051%22%2C%220%22%2C%221280%22%2C%22AGY%22%2C%22%22%5D%5D"
and extract the part marked in bold letters.
Assuming the format is constant:
awk -F";" '{sub(".*:","",$8);print $8}'
Regards
Unfortunately the format is not constant, the position of the JSESSIONID parameter varies.
Use nawk or /usr/xpg4/bin/awk on Solaris.
awk 'NF>1&&$0=$2' FS="JSESSIONID=[^:]*:" RS=";" input
perl -lne'print $1 while /JSESSIONID=.*?:(.*?);/g' input
Ok, thanks! Both work.