使用 bash 将数字、字符串从一行中分离出来

HUY*_*HUY 6 command-line sed awk text-processing

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

示例:我有一个包含

string123anotherstr456thenanotherstr789

输出应该是:

string
123
anotherstr
456
thenanotherstr
789
Run Code Online (Sandbox Code Playgroud)

Rom*_*est 21

GNUgrep或兼容的解决方案:

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

输出:

string
123
anotherstr
456
thenanotherstr
789
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 5

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
Run Code Online (Sandbox Code Playgroud)


小智 5

awk

输入仅包含字母和数字

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

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

(这&awk匹配序列的简写。)


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

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

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

负数和小数

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

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

这些字符必须同时出现在[[: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
Run Code Online (Sandbox Code Playgroud)

读者练习

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

  • 确保-仅当它出现在数字序列的开头时才算作数字的一部分。
  • 允许以科学记数法表示的数字。