4

How can I extract the beginning alphabetic letters from a string? I want to extract alphabets occurring in the beginning before I hit the first non-alphabetic character.

e.g. If the input string is abcd045tj56 the output should be abcd

Similarly, if the input is jkl657890 the output should be jkl

Can it be done in shell script using awk/sed/cut?

I tried

echo "XYZ123" | awk 'sub(/[[:alpha:]]*/, "")'

But it gives 123 instead of xyz

Then I tried

echo "XYZ123" | awk '{print (/[[:alpha:]]*/)}'

but it gives 1

I want the answer to be XYZ

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Try something like `awk 'match($0,/^[a-zA-Z]+/){print substr($0,RSTART,RLENGTH)}' Input_file` should work in any version of `awk`. – RavinderSingh13 Jul 27 '23 at 06:55

7 Answers7

5

Converting my comment to an answer here. Using any awk version.

awk '
match($0,/^[a-zA-Z]+/){
  print substr($0,RSTART,RLENGTH)
}
' Input_file

OR:

awk '
match($0, /[^[:alpha:]]/){
  print substr($0, 1, RSTART-1)
}
' Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
4

You may use this sed:

sed 's/[^[:alpha:]].*$//'

This sed matches a non-alpha character and everything afterwards and substitutes with an empty string.

Examples:

sed 's/[^[:alpha:]].*$//' <<< 'abcd045tj56'
abcd

sed 's/[^[:alpha:]].*$//' <<< 'XYZ123'
XYZ

sed 's/[^[:alpha:]].*$//' <<< 'jkl657890'
jkl

If you want to do this in bash then:

s='abcd045tj56'
echo "${s/[^[:alpha:]]*}"

abcd
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • N.B. This will print leading alpha characters even if no substitution occurs i.e. if a string only consists of alpha characters it will print it however the OP stipulated "I want to extract the alphabets occurring in the beginning before I hit first non-alphabetic character". This may be achieved either `sed 's/^[^[:alpha:]].*$//p;d' file` or `sed -n 's/^[^[:alpha:]].*$//p' file` – potong Jul 28 '23 at 07:26
  • I think OP needs to clarify this case when `string only consists of alpha characters only` – anubhava Jul 28 '23 at 08:40
2

Use grep:

$ grep -Eo '^[A-Za-z]+' <<<"XYZ123"

to only match alphabetic letters at the beginning of the string.

Paolo
  • 21,270
  • 6
  • 38
  • 69
1

You can use awk with a non-alphabet as the field separator so you can get the leading alphabets by printing the first field:

awk -F'[^[:alpha:]]' '{print $1}'

Demo: https://awk.js.org/?snippet=g7eajb

blhsing
  • 91,368
  • 6
  • 71
  • 106
1

You can use bash's parameter expansion to remove the first non-alphabet and all characters after it:

s=XYZ123
echo ${s%%[^[:alpha:]]*}

Demo: https://onlinegdb.com/OzjGf53T-

Note that this approach has the performance benefit of avoiding the overhead of spawning a separate process.

blhsing
  • 91,368
  • 6
  • 71
  • 106
1

I tried

echo "XYZ123" | awk 'sub(/[[:alpha:]]*/, "")'

But it gives 123 instead of xyz

You instructed GNU AWK to replace zero-or-more alphabetic characters using empty string, if you wish to do this task using sub select non-alpha character followed by zero-or-more any characters, namely

echo "XYZ123" | awk '{sub(/[^[:alpha:]].*/, "");print}'

gives output

XYZ

(tested in GNU Awk 5.1.0)

Daweo
  • 31,313
  • 3
  • 12
  • 25
1

Using gnu awk you can print the first 1 or more alphabetic letters:

echo "XYZ123" | awk 'match($0, /[[:alpha:]]+/, a) {print a[0]}'

Output

XYZ

If there should be at least a single a non alphabetic character following, you can use a capture group and print that value:

echo "XYZ123" | awk 'match($0, /([[:alpha:]]+)[^[:alpha:]]/, a) {print a[1]}'
The fourth bird
  • 154,723
  • 16
  • 55
  • 70