Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a string that is always 3 characters... the first one and the last one are always the same.

example:

▁▅█

Is there a simple way to only display the one in the middle? (which is the only one that changes)

share|improve this question
up vote 8 down vote accepted

Yes, try doing this, and pick your preferred method =) :

With :

echo "ixi" | grep -oP "^.\K."

With :

echo "ixi" | cut -c2

With parameter expansion :

x='ixi'; echo ${x:1:1}

With :

echo "ixi" | sed 's/.\(.\)./\1/'

or

echo "ixi" | sed 's/\(^.\|.$\)//g'

With :

echo "ixi" | perl -lne 'print $& if /^.\K./'

With :

echo "ixi" | ruby -ne 'print $_.split(//)[1]'

With :

echo 'ixi' | awk '{split($0, a, ""); print a[2]}'

With :

echo "ixi" | python -c 'print list("'$(cat)'")[1]'

or

python -c 'import sys; print list(sys.argv[1])[1]' ixi

NOTE

  • \K restart the match to zero (see pcre doc)
  • $(cat) in python is a shell hack to get STDIN
share|improve this answer
3  
+1 for the nice use of grep. – Dave Jarvis Nov 15 '12 at 17:11
3  
Added the sortest one : cut – Gilles Quenot Nov 15 '12 at 17:36
    
loved that grep – Mr.Gando Nov 16 '12 at 4:35

You could also use sed instead of grep:

sed 's/.\(.\)./\1/'

This says:

  1. s/ ... match the expression up to the next / character.
  2. . ... match the first character (any).
  3. \(.\) ... match the next character and remember it.
  4. . ... match the third character (any).
  5. / ... denotes the end of the expression.
  6. \1 ... replace the entire string that matched with the character that was remembered.
  7. / ... end of replacement text.

Thus:

$ echo "abc" | sed 's/.\(.\)./\1/'

Will print:

b
share|improve this answer

        ︙
or

echo "ixi" | awk '{print substr($0,2,1)}'

or

expr "ixi" : '.\(.\).'
share|improve this answer

For variety, here's one way with dd:

echo ixi | dd bs=1 skip=1 count=1 2>/dev/null

If your grep doesn't support perl (-P), you could do it like this:

echo ixi | grep -o . | sed -n 2p

These alternatives only work for one-line input.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .