给定一个没有固定字段分隔符模式的输入行,如下所示。
x="15:23:46 Let's do this 15:23:47 It's easy: to do for you 15:23:48 You will ## have solution soon 0"
我试图根据时间戳模式将其分成单独的行,因此预期输出如下。
15:23:46 Let's do this
15:23:47 It's easy: to do for you
15:23:48 You will have solution soon
0
请注意,行尾有 0,也应该打印在换行符上。我需要将其用作其余代码的返回状态。
当时间戳不同时,我能够获得结果,但是当其中一些时间戳相同时,就会导致意外的输出。
x=”15:23:46我们开工吧15:23:46这很简单:为您做 15:23:48 您很快就会 ## 找到解决方案 0"
观察现在我们有两个相同的时间戳。这就是我被困住的地方。预期输出应该是:
15:23:46 Let's do this
15:23:46 It's easy: to do for you
15:23:48 You will have solution soon
0
我使用的逻辑是获取数组中的所有时间戳,然后迭代时间戳的数量并 grep 查找所需的数据。当具有唯一时间戳时,对我有用的逻辑如下。
#!/bin/sh
timestamp=()
x="15:23:46 Let's do this 15:23:47 It's easy: to do for you 15:23:48 You will have solution soon 0"
timestamp+=(`echo $x | grep -oP '(?>[0-9]{2}:[0-9]{2}:[0-9]{2})'`)
total_timestamps=`echo $x | grep -oP '(?>[0-9]{2}:[0-9]{2}:[0-9]{2})' | wc -l`
status=-1
for i in `seq $total_timestamps`
do
if [ "$i" -ne "$total_timestamps" ]; then
echo $x | grep -oP "(?=${timestamp[i-1]}).*(?=${timestamp[i]})"
fi
if [ "$i" -eq "$total_timestamps" ]; then
echo $x | grep -oP "(?=${timestamp[i-1]}).*(?=${timestamp[i]})" | awk '{$NF=""}1'
status=`echo $x | grep -oP "(?=${timestamp[i-1]}).*(?=${timestamp[i]})" | awk '{print $NF}'`
fi
done
echo $status
当时间戳在单行中的某些或许多地方相同时,有人可以帮助我,或者将我重定向到已解决类似问题的地方吗?
答案1
使用用于多字符 RS 和 RT 的 GNU awk:
$ awk -v RS='([0-9]{2}(:[0-9]{2}){2})|(0\n$)' 'NR>1{print pRT $0} {pRT=RT} END{printf "%s", RT}' <<<"$x"
15:23:46 Let's do this
15:23:47 It's easy: to do for you
15:23:48 You will ## have solution soon
0
或者如果您的 shell 没有<<<
运算符:
$ echo "$x" | awk -v RS='([0-9]{2}(:[0-9]{2}){2})|(0\n$)' 'NR>1{print pRT $0} {pRT=RT} END{printf "%s", RT}'
15:23:46 Let's do this
15:23:47 It's easy: to do for you
15:23:48 You will ## have solution soon
0
如果您想从输出行中去除尾随空白,只需更改print pRT $0
为print pRT gensub(/\s+$/,"",1,$0)
.
答案2
使用GNU sed
启用了扩展正则表达式模式的流编辑器实用程序-E
。
我们在(日期字符串或末尾的一个零)左侧查找一串空格,并将其更改为换行符。然后使用标准习惯用法P;D
打印换行符左侧的所有内容,然后将其截断。冲洗并重复,直到整个图案空间被耗尽。
printf '%s\n' "$x" |
sed -Ee '
s/\s+(([0-9]{2}(:[0-9]{2}){2})|0$)/\n\1/
P;D
' - | cat -A
15:23:46 Let's do this$
15:23:47 It's easy: to do for you$
15:23:48 You will ## have solution soon$
0$