I have a string comprised of multiple substrings, separated by underscores. For example: AbcdAEfd_hEgdgE_AbAAAAA. I need to remove all vowels except the first from each substring. So:

  • AbcdAEfd -> Abcdfd
  • hEgdgE -> hEgdg
  • AbAAAAA -> Ab

The resulting string should be Abcdfd_hEgdg_Ab


Pure bash solution, using just parameter substitution:

#! /bin/bash
vowel=${prefix: -1}
prefix=${prefix%?}                  # Remove the vowel from the prefix
suffix=${suffix//[aeiou]/}          # Remove the vowels.
echo "$1 -> $prefix$vowel$suffix."
  • 1
    What's the point of removing the $vowel from the prefix only to add it back at the end? Am I missing something? – jw013 Jul 6 '12 at 15:58
  • @jw013: If you only want to print it, there's probably no point. For testing, though, it is useful :-) – choroba Jul 6 '12 at 16:07

You can use perl's zero-width look-behind regex syntax.

perl -pe "s/(?<=[aeiou])([^aeiou_]*)[aeiou]([^aeiou_]*)/\1\2/ig"

This next snippet treats an input line as a single string (not multiple sub-strings).

perl -pe "s/(?<=[aeiou])([^aeiou]*)[aeiou]/\1/ig"
  • hi peter this one is working fine but the thing is _ must be the delimter for the second occurence of the vowel not the entire word – newuser Jul 4 '12 at 10:14
  • You had better give clear examples as an update to your question (not in the comments, as they usually don't show things as clearly) ... It is a bit confusing when you say it works fine, and it produces the output stated in your question, and you now mention a delimiter.. I just don't know what you mean by that (I can only guess). – Peter.O Jul 4 '12 at 10:22
  • iam sorry i got confused...let me give a clear example ABCDAEFD_EHGDGE_ABAAAAA in this word the output should be ABCDFD_EHGDGE_AB . again iam sorry i should have given correct example – newuser Jul 4 '12 at 10:30
  • Peter.O i guess this is clear? – newuser Jul 4 '12 at 10:39
  • 1
    @anonymous: you should put the specs in your question. That way everyone coming to the page will see what you want. Here only the people who can be bothered enough to read the comments will see it... Re; what you've just presented, it still seems(?) to be wrong? why does the second word have a trailing E? I think what you are asking for is to leave only the first vowel in any _ delimited word.. (but I don't know for sure)... In any case. put the specs in your question (just prefix it with the word UPDATE: or something like that)... – Peter.O Jul 4 '12 at 10:54

Does python count? This should work:

cat anonymous.txt | python -c "import sys; x=sys.stdin.read(); print(x[0]+''.join([z for z in x[1:] if z not in 'AEIOUaeiou']))"

I tried with tee and named pipes as well, but it kinda failed:

makefifo pipe; cat anonymous.txt | tee >(cut -b1 >> pipe&) >(cut -b1- | tr -d aeiouAEIOU >> pipe&) > /dev/null; cat pipe | xargs -d '\n'

This might work for you (GNU sed):

sed 's/^/\n/;ta;:a;s/\n$//;t;s/\n\([^aeiou_]*[aeiou]\)/\1\n/i;:b;s/\n\([^aeiou_]*\)[aeiou]/\1\n/i;tb;s/\n\([^aeiou]*\)/\1\n/i;ta' file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.