Unixでタイムスタンプを使用して1行を複数行に分割する

Unixでタイムスタンプを使用して1行を複数行に分割する

以下のように固定されたフィールド区切りパターンのない入力ラインが提供されます。

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

行の末尾にゼロがあることに注意してください。これは改行文字にも印刷する必要があります。これを残りのコードの戻り状態として使用する必要があります。

タイムスタンプが異なると結果が得られますが、一部が同じ場合は予期しない出力が発生します。

x=”15:23:46始めましょう15:23:46簡単です: あなたのためにしてみてください 15:23:48 あなたは ## すぐに解決策を見つけるでしょう 0"

次に、2つの同じタイムスタンプがあることを確認してください。これが私が付いているところです。予想される出力は次のようになります。

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

<<<またはシェルに演算子がない場合:

$ 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

(日付文字列または末尾の0)左側の空白文字列を見つけ、それを改行文字に変更します。次に、標準イディオムを使用して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$

関連情報