Extract string between two different characters

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.