如何在bash/ash脚本中提取字符串开头的字母字符?
提取字符串开头的连续字母字符
下面分别用awk、sed、cut三种Shell工具实现需求:
用awk实现
你之前用sub命令是替换匹配内容,所以会删掉开头字母留下其他部分,换个思路匹配开头的字母序列即可:
echo "abcd045tj56" | awk '{match($0, /^[[:alpha:]]+/); print substr($0, 1, RLENGTH)}'
更简洁的捕获组写法:
echo "jkl657890" | awk 'match($0, /^([[:alpha:]]+)/, arr) {print arr[1]}'
说明:^[[:alpha:]]+精准匹配字符串开头的连续字母,match函数找到匹配内容后,RLENGTH记录匹配长度,用substr截取对应片段;第二种写法把匹配的字母存入数组arr,直接输出捕获的内容。
用sed实现
通过替换掉第一个非字母及后续所有内容,就能保留开头的字母:
echo "abcd045tj56" | sed 's/[^[:alpha:]].*//'
也可以用捕获组明确保留开头字母:
echo "jkl657890" | sed 's/^\([[:alpha:]]*\).*/\1/'
说明:第一种写法里,[^[:alpha:]].*匹配第一个非字母字符和后面的所有内容,替换为空后就只剩开头的字母;第二种写法捕获开头的字母序列,将整行替换为捕获的内容。
用cut实现
cut本身不支持正则,需要结合grep定位第一个非字母的位置再截取:
# 示例:处理abcd045tj56 str="abcd045tj56" pos=$(echo "$str" | grep -bo '[^[:alpha:]]' | head -n1 | cut -d: -f1) echo "$str" | cut -c1-$((pos-1))
如果字符串全是字母,上面的命令会报错,加个判断兼容这种情况:
str="jkl657890" pos=$(echo "$str" | grep -bo '[^[:alpha:]]' | head -n1 | cut -d: -f1) if [ -z "$pos" ]; then echo "$str" else echo "$str" | cut -c1-$((pos-1)) fi
说明:grep -bo输出匹配字符的字节位置,head取第一个非字母的位置,cut提取位置数字后,用cut截取到该位置的前一个字符;如果没有非字母字符,直接输出原字符串。
内容的提问来源于stack exchange,提问作者Deepali Joshi
相关产品推荐
相关产品推荐

