我试图仅使用 awk
从 bash 中的字符串中找到最长的数字序列。我已经形成了以下命令,它给了我输出。
$ echo "This_is_1234_and_44448888_1234567_111111_23456789_and_234" | sed 's/./n&/g' | awk 'BEGIN{max_length=0} { tmp=match($1,/[0-9]/) ; if (tmp) { numbers[i]=numbers[i]$0;non_digit=0;} else if (non_digit<1) { non_digit=2 ;i++; } } END { i=0; for (key in numbers) { current_length=length(numbers[key]); if (current_length > max_length) { max_length = current_length; i = 0;} if (current_length >= max_length) {i++; max_length_strings[i] = numbers[key];} } print "max_length for the consecutive number portion is ",max_length; for ( j in max_length_strings ) { print "String_Part: " max_length_strings[j] " and Length: " max_length; }}'
max_length for the consecutive number portion is 8
String_Part: 23456789 and Length: 8
String_Part: 44448888 and Length: 8
但是为了从字符串中获取每个字符以进行数字检查,我正在使用sed
命令。
那么,如何避免使用 sed 并使用单个 awk
命令来实现相同的结果呢?
只使用 awk:
s="This_is_1234_and_44448888_1234567_111111_23456789_and_234"
awk -v RS='[^[:digit:]]+' 'length($0) >= max{
max=length($0)
num[max]=(num[max]?num[max] "," $0:$0)
}
END {
printf "max length=%s, numbers: %sn", max, num[max]
}' <<< "$s"
max length=8, numbers: 44448888,23456789
解释:
- 使用自定义
RS='[^[:digit:]]+'
我们将记录分隔符制作为 1 个或多个非数字字符,因此每条记录都成为数字字段 - 然后,我们检查每条记录的长度(所有数字字段),并不断更新
max
块中的变量length($0) >= max
- 我们还将所有最大长度字段保留在数组
num
- 在
END
块中,我们只打印max
并num
数组条目 - 由于多字符
RS
,这是gnu-awk
特定的
使用 GNU awk 4.* 用于 FPAT 和真正的多维数组:
$ cat tst.awk
BEGIN { FPAT="[0-9]+" }
{
delete strs
for (i=1;i<=NF;i++) {
cur = length($i)
strs[cur][$i]
max = (i>1 && cur>max ? cur : max)
}
for (str in strs[max]) {
printf "String_Part: %s and Length: %dn", str, max
}
}
$ awk -f tst.awk file
String_Part: 23456789 and Length: 8
String_Part: 44448888 and Length: 8
上面假设您希望每个输入行的最大值输出,而不是整个文件的输出。如果你确实想要它在整个文件中,那么再次使用GNU awk(用于RT):
$ cat tst.awk
BEGIN { RS="[0-9]+" }
{
cur = length(RT)
strs[cur][RT]
max = (NR>1 && cur>max ? cur : max)
}
END {
for (str in strs[max]) {
printf "String_Part: %s and Length: %dn", str, max
}
}
$ awk -f tst.awk file
String_Part: 23456789 and Length: 8
String_Part: 44448888 and Length: 8