私の入力ファイルには次のデータが含まれています。
acb/xyz/row<t>
acb/xyz/row<t>
abc/xyz/row<b>
abc/xyz/row<b>
abc/xyz/row<0>
abc/xyz/row<0>
abc/xyz/row<1>
abc/xyz/row<1>
abc/xyz/row<2>
abc/xyz/row<2>
abc/xyz/row<3>
abc/xyz/row<3>
abc/xyz/row<4>
abc/xyz/row<4>
だから、出力は次のようになりたいです。
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
- 上記の各セクタには複数行が含まれています。ここでは、セクタごとに2行だけを表示します。
- 上、下、0から30までのセクタがあります。ここでは最大4つのセクタを表示します。
セクタの1つを取得するためにsedコマンドを使用してみました。
sed '/row<1>/i #Sector 1' myfile
これは私に次のような結果を与えます:
#Sector 1
abc/xyz/row<1>
#Sector 1
abc/xyz/row<1>
すべてのゲームの前に改行する必要はなく、すべてのセクションの最初のゲームの前に改行するだけです。
答え1
awkを使用してください。
$ cat tst.awk
BEGIN {
FS = "[<>]"
map["t"] = "Top"
map["b"] = "Bottom"
}
{
sector = $(NF-1)
if ( sector != prev ) {
print "#Sector", (sector in map ? map[sector] : sector)
prev = sector
}
print
}
$ awk -f tst.awk file
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
答え2
N;P;D
ループを使用してこれを行い、sed
行番号が変更された場合にのみ行を挿入できます。#Sector
sed -E 'N;P;/^(.*)\n\1/D;s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/;P;D'
これで、次のようにしてtop
部分の処理を追加する必要があります。bottom
sed -E -e '1i #Sector top' -e 'N;P;/^(.*)\n\1/D;s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/;s/#Sector b/&ottom/;P;D'
上海:
- オプションは、
-E
出力を読みやすくすることです。代わりに、(…)
これらの部分に8つのバックスラッシュを追加することもできます。 1i #Sector top
最初のセクターヘッダーのみを追加してください。- これで、常に2行を一緒に処理し、最初の行を印刷する
N
ために常に拡張行を追加します。P
/^(.*)\n\1/
は最初の行で繰り返される表現なので、セクションヘッダーを挿入する理由がないので、最初の行を削除して2行目にD
進みます。- 今正規表現の魔法を試してみてください。最初の行(すでに印刷されています!)を
s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/
セクションタイトルと()
3番目のペアから抽出された行番号に置き換えます。 - 最後に、単に
b
次に変更します。bottom
s/#Sector b/&ottom/
P
D
最初の行を印刷して削除し、2行目を続行してループを閉じます。
答え3
GNUの使用sed
$ sed -Ez 's/(\S+row<([^>]*)>)(.*\1)?/#Sector \2\n&/g;s/\<t\>/Top/;s/\<b\>/Bottom/' input_file
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
答え4
次のスクリプトは bash シェルで実行されます。
#!/bin/bash
awk 'BEGIN{ FS="/" }
{a=$3;
if(a != b)
print "Sector " substr(a,5,1)"\n" a
else
print a;
b=$3}' myfile.txt