awk

awk

如何使用 bash 命令将字符串和数字从一行中分离出来。

示例:我有一个包含

string123anotherstr456thenanotherstr789

输出应该是:

string
123
anotherstr
456
thenanotherstr
789

答案1

GNUgrep或兼容的解决方案:

s="string123anotherstr456thenanotherstr789"
grep -Eo '[[:alpha:]]+|[0-9]+' <<<"$s"
  • [[:alpha:]]+|[0-9]+- 正则表达式交替组,匹配字母字符或数字;两者都将被视为输出中的单独条目

输出:

string
123
anotherstr
456
thenanotherstr
789

答案2

awk

输入仅包含字母和数字

[[:alpha:]]+在每个(字母序列)和每个[[:digit:]]+(数字序列)之后添加换行符:

awk '{ gsub(/([[:alpha:]]+|[[:digit:]]+)/,"&\n",$0) ; printf $0 }' filename

&awk匹配序列的简写。)


输入包含其他字符(例如标点符号)

和以前一样,但现在还处理[^[:alnum:]]+(非字母、非数字)字符的子字符串:

awk '{ gsub(/([[:alpha:]]+|[[:digit:]]+|[^[:alnum:]]+)/,"&\n",$0) ; printf $0 }' filename

负数和小数

-(连字符)和.(句号)视为数字:

awk '{ gsub(/([[:alpha:]]+|[[:digit:].-]+|[^[:alnum:].-]+)/,"&\n",$0) ; printf $0 }' filename

这些字符必须出现在[[:digit:].-]+[^[:alnum:].-]+表达式中。此外,要被解释为字面连字符,必须-最后的每个表达式最后一个右方括号之前的字符;否则,表示范围的字符。

例子:

[test]$ cat file.txt 
string123another!!str456.001thenanotherstr-789

[test]$ awk '{ gsub(/([[:alpha:]]+|[[:digit:].-]+|[^[:alnum:].-]+)/,"&\n",$0) ; printf $0 }' file.txt 
string
123
another
!!
str
456.001
thenanotherstr
-789

给读者的练习

如果输入文件需要它,您可以将awk命令修改为:

  • 确保-仅当出现在开始的数字序列。
  • 允许以科学记数法表示的数字。

答案3

POSIXly:

string=string123anotherstr456thenanotherstr789
sed '
  s/[^[:alnum:]]//g; # remove anything other than letters and numbers
  s/[[:alpha:]]\{1,\}/&\
/g; # insert a newline after each sequence of letters
  s/[0-9]\{1,\}/&\
/g; # same for digits
  s/\n$//; # remove a trailing newline if any' << EOF
$string
EOF

答案4

python3

python3 -c '
from itertools import groupby
s = ("".join(g) for k, g in 
    groupby("string123anotherstr456thenanotherstr789", lambda x: x.isalpha()))
print(*s, sep="\n")
'

string
123
anotherstr
456
thenanotherstr
789

相关内容