user2301752
user2301752

Reputation: 11

Bash - extracting a string between two points

For example:

((

extract everything here, ignore the rest

))

I know how to ignore everything within, but I don't know how to do the opposite. Basically, it'll be a file and it needs to extract the data between the two points and then output it to another file. I've tried countless approaches, and all seem to tell me the indentation I'm stating doesn't exist in the file, when it does.

If somebody could point me in the right direction, I'd be grateful.

Upvotes: 1

Views: 860

Answers (4)

Bernhard
Bernhard

Reputation: 8831

sed -n '/^((/,/^))/ { /^((/b; /^))/b; p }'

Brief explanation:

/^((/,/^))/: range addressing (inclusive)
{ /^((/b; /^))/b; p }: sequence of 3 commands
                       1. skip line with ^((
                       2. skip line with ^))
                       3. print

The line skipping is required to make the range selection exclusive.

Upvotes: 0

clt60
clt60

Reputation: 63892

If your data are "line oriented", so the marker is alone (as in the example), you can try some of the following:

function getdata() {
    cat - <<EOF
before
((
    extract everything here, ignore the rest
    someother text
))
after
EOF
}

echo "sed - with two seds"
getdata | sed -n '/((/,/))/p' | sed '1d;$d'

echo "Another sed solution"
getdata | sed -n '1,/((/d; /))/,$d;p'

echo "With GNU sed"
getdata | gsed -n '/((/{:a;n;/))/b;p;ba}'

echo "With perl"
getdata | perl -0777 -pe "s/.*\(\(\s*\\n(.*)?\)\).*/\$1/s"

Ps: yes, its looks like a dance of crazy toothpicks

Upvotes: 2

pfnuesel
pfnuesel

Reputation: 15310

Assuming you want to extract the string inside (( and )):

VAR="abc((def))ghi"
echo "$VAR"
VAR=${VAR##*((}
VAR=${VAR%%))*}
echo "$VAR"

## cuts away the longest string from the beginning; # cuts away the shortest string from the beginning; %% cuts away the longest string at the end; % cuts away the shortes string at the end

Upvotes: 1

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185025

The file :

$ cat /tmp/l
((
    extract everything here, ignore the rest
    someother text
))

The script

$ awk '$1=="((" {p=1;next} $1=="))" {p=o;next} p' /tmp/l
    extract everything here, ignore the rest
    someother text

Upvotes: 0

Related Questions