tac コマンドオプションが奇妙な出力を生成します。 【問題の理解】

tac コマンドオプションが奇妙な出力を生成します。 【問題の理解】

次の内容のみを含むファイルがあるとします。

a
b
c
b
a

tac --separator=a file[DebianベースのLinuxで] BASHを使用すると、次のようになります。

                  # empty line
                  # empty line
b
c
b
aacommand@prompt  # two a just before the prompt


質問:私が理解しているところ--separator=aによるとanewlineこれは正しいですか?

より多くの入力のために別の文字列を試してみましたが、結果は乱雑です。他のオプションはすべてうまくいくと思います。を使用すると、tac --before最初は約5〜1本の空行が表示されますが、実際にはそのようなことが発生することになっています。そうですか?

答え1

tac区切り文字がレコードの終端である場合、つまり、区切り文字が最後のレコードの後に​​表示される場合の基本設計用途の文脈で理解するのは簡単です。レコードを逆順に印刷します(各ターミネーターを含む)。

$ echo -n fooabara | tac -s a; echo
rabafooa

入力は3つのレコード(foobおよびr)で構成され、それぞれの後に区切り文字が続きます。a出力は3つのレコード(rbおよびfoo)で構成され、各レコードの後に​​区切り文字が続きますa

最後のレコードがレコードターミネータで終わらない場合でも、レコード区切り文字なしで最初に印刷されます。

$ echo -n fooabar | tac -s a; echo
rbafooa

最後のレコードの末尾に区切り文字がないため、最後のレコードは区切り文字なしでr2番目のレコードに関連付けられます。b

改行のため、入力内容が少し歪んでいるようです。改行文字の代わりにコンマを使用して見てみましょう。

$ echo -n a,b,c,b,a, | tac -s a; echo
,,b,c,b,aa

3 つの入力レコードがあります。空のレコード(終了者があるa)、大きなレコード,,b,c,b,(やはり終了者がある)、,終了していないレコードがあります。レコード(終了者を持たない最後のレコードを除いて、それぞれ終了者がある)は、逆の順序で印刷されます。

あなたの混乱は、おそらく「区切り記号」が区切り記号であると予想したことに起因しています。しかし、これは間違った名前です。実際にはレコードの終端者です。--beforeイニシエータとして作成します。

答え2

次の例は、この--regexオプションを使用するのに役立ちます。

$ cat records 
---1---
1
2
3
---2
A
B
C
---3--
a
b
c
$ tac --before --regex --separator=^---[0-9]+-*$ records
---3--
a
b
c
---2
A
B
C
---1---
1
2
3

この例では、ファイルにはrecords複数行のレコードが含まれています。各行は^...$()で始まる行で始まり---、その後に数字([0-9]+)とオプションのマイナス記号(-*)の順に続きます。各レコードの行順序とヘッダー行が保持されていることがわかります。

tacTwitterなどのフィードアプリケーションで使用されているように、ログファイルエントリを逆順に表示するためにこの機能を使用します。たとえば、最後の2つのレコードのみを逆順に印刷するには、次のようにします。

tac --before --regex --separator=^---[0-9]+-*$ example \
 | awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'

関連情報