如何使用 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