私の入力ファイル:
{empty line}
Test #1
data
{empty line}
Test #2
data
{empty line}
Test #3
{empty line}
Test #4
data
{empty line}
Test #5
予想出力:
1
2
4
単純なbashスクリプトを使用して各テストで利用可能なデータがある場合は、シリアル番号(ハッシュタグの後)をどのように取得できますか?
編集:各テストのデータには、日付、時刻、違いなどのいくつかの値が含まれています。 2つのテストの間に2つ以上のデータラインがあります。各テストの間には空行があります。 「テスト」数字は常に1から始まり、厳密に増加する正の整数です。
答え1
これを行うことができます:
awk -F ' #' '
function maybePrint() {
if (NR > 1 && NR > lastLine + 1) {print lastSeq}
}
$1 == "Test" {
maybePrint()
lastSeq = $2
lastLine = NR
}
END {
maybePrint()
}
' file
要件を変更するのは良いことではありませんが、パズルが好きなので、ファイルに空白行がある場合:
sed -n '
/^Test #/ {
s///
=
p
}
$=
' file \
| paste - - \
| awk -F '\t' '
NR > 1 && $1 - prevLine > ($2 ? 2 : 0) {print prev}
{prevLine = $1; prev = $2}
'
答え2
データにハッシュタグがない場合:
sed -n 'N;/#.*#/D;s/.*#//;P' file
より明確なオプション:
sed -nE 'N;/(.*#)[0-9]+\n\1/D;s/.*#//;P' file
パターンは(.*#)[0-9]+\n\1
ハッシュタグを使用して重複行を追跡します。
答え3
を使用する場合は、sed
通常、N;P;D
モードと予約済みスペースの使用から選択します。
N;P;D
方法
N
この方法では、最初に1つを追加し、最初の行のみをP
印刷D
し、最初の行を削除して新しいループを開始し、バッファに常に2つの連続した行を保持できます。
sed '$!N;/\ndata/!D;s/.*#//;P;D'
$!N
まだ最後の行ではない場合は、次の行を追加してください。/\ndata/
2 番目のラインの二重ラインと一致しdata
、!
一致を反転させた後、D
バッファの 2 番目のラインだけで次のループを開始します。したがって、2行目が始まらない場合は、data
次のペアに進んでください。- ここに到達すると、2行目がで始まることがわかるので、
data
それs/.*#//
までのすべての内容は削除され、最初の行#
はP
印刷され(今数字のみが表示されます)、次のループの最初の行は削除されます(ここのD
2行に注意してください)。data
場合は、何をすべきかわからない。
待機空間へのアクセス
古いスペースから情報を印刷したい行を保持しますがh
、トリガーする行にのみ印刷してください。
sed '/data/!{h;d;};x;s/.*#//'
/data/!
すべて含まれていないアドレスdata
を入力しh
てd
出力なしで再開するには、削除してください。- ここで
data
一致している場合は、バッファを変更して保存された行をパターン空間に取り込み、x
内容を削除してから、デフォルトの出力で結果を印刷します。#
s/.*#//
答え4
awk '{a[++i]=$0}/data/{for(x=NR-1;x<=NR;x++)print a[x]}' file| awk -F "#" '/Test/{print $2}'
出力
1
2
4