我在 bash 中有一个test_file,它在屏幕上输出。我无法控制上游代码以某种方式打印它们。因此,我需要从屏幕输出中解析一些值。这是我正在做的事情:
MyOut=$(./my_test_file.sh) # this is my example script which echo's the
#output
echo $MyOut
向我展示以下内容
output for different segments IP address: 192.168.0.12 Segment :0xfff Segment Data: 123 23 42 23 4 444 1121 8676 34 530 323 564 523 7878 7328 96
我的预期结果将是一个字符串变量
123,23,42,23,4,444,1121,8676,34,530,323,564,523,7878,7328,96
逗号分隔的 16 个值存储在某个变量中,我可以将其转储到文本文件中以供进一步处理。
我尝试使用正则表达式,只想在以下输出中提取最后 16 个数字
我做到了
numbers=$(echo $MyOut | grep -o -E '[0-9]+')
给我
192 168 0 12 0 123 23 42 23 4 444 1121 8676 34 530 323 564 523 7878 7328 96
我需要提取最后 16 个数字。由于它不是数组格式,我可以在正则表达式中添加一些东西,它只吐出逗号分隔的最后 16 个数字???
顺便说一句,如果您需要研究my_test_file.sh,它只是呼应语句
#!/bin/bash
echo "output for different segments "
echo "IP address: 192.168.0.12 Segment :0xfff"
echo "Segment Data:"
echo "123"
echo "23"
echo "42"
echo "23"
echo "4"
echo "444"
echo "1121"
echo "8676"
echo "34"
echo "530"
echo "323"
echo "564"
echo "523"
echo "7878"
echo "7328"
echo "96"
谢谢灰
MyOut=$(./my_test_file.sh | tail -n +4 | paste -sd ",")
tail -n +4
将跳到输出的第 4 行,paste
将用逗号而不是空格连接这些行。
在评论中,您提到您无法访问paste
- tr
呢?
MyOut=$(./my_test_file.sh | tail -n +4 | tr 'n' ',')
仅使用 awk
:
./my_test_file.sh |awk -vlast=16 -v RS= '{gsub(/[^[:digit:]]/," ") ; for(i=NF-last+1;i<=NF;i++) if(i!=NF)printf $i",";else print $i}'
123,23,42,23,4,444,1121,8676,34,530,323,564,523,7878,7328,96
首先使用 gsub()
函数从每行中删除所有非数字字符,后来循环用于最后 16 列。 printf
和 print
都用于处理最后一个逗号字符。
下面是一个示例 awk 脚本:
text="output for different segments IP address: 192.168.0.12 Segment :0xfff Segment Data: 123 23 42 23 4 444 1121 8676 34 530 323 564 523 7878 7328 96"
echo $text |awk '{sub(/^.*Segment Data: /,"");gsub(/ /,",")}1'
输出:
123,23,42,23,4,444,1121,8676,34,530,323,564,523,7878,7328,96
外植:
sub(/^.*Segment Data: /,"")
从行开始到Segment Data:
中删除文本
gsub(/ /,",")
全部替换为
1
my_test_file.sh
打印修改行
其他方式:
echo "output for different segments IP address: 192.168.0.12 Segment :0xfff Segment Data: 123 23 42 23 4 444 1121 8676 34 530 323 564 523 7878 7328 96" | awk -F'Segment Data: ' '{print $2}' | sed 's/ /,/g'
给你:
123,23,42,23,4,444,1121,8676,34,530,323,564,523,7878,7328,96
试试这个 Shellcheck-clean 纯 Bash 代码:
#! /bin/bash -p
myout=$(./my_test_file.sh)
read -r -d '' -a parts <<<"$myout"
numlist=${parts[*]: -16}
result=${numlist// /,}
printf '%sn' "$result"
- 使用问题中给出的
123,23,42,23,4,444,1121,8676,34,530,323,564,523,7878,7328,96
,它打印read
. - 该代码假定 IFS 具有其默认值。
myout
将parts
值的空格分隔部分放入数组-d ''
中。read
导致-r
继续通过换行符(否则它会在读取第一行后停止(-r
选项禁用了输入中反斜杠的奇怪处理(这在这里无关紧要,但始终将read
与numlist=${parts[*]: -16}
一起使用是最安全的,如果缺少,Shellcheck 会发出警告(。-
numlist
将parts
字符串设置为$IFS
数组的最后 16 个元素,由result=${numlist// /,}
的第一个字符(默认情况下为空格字符(分隔。 -
result
numlist
设置为 CC_31 的值,所有空格字符都替换为逗号。