このファイルには何も入っていないとします
a
b
c
b
a
tac --separator=a file
BASH [Debian ベースの Linux 上] で使用すると、次のようになります。
# empty line
# empty line
b
c
b
aacommand@prompt # two a just before the prompt
質問: 私の理解では、ではなく が文字列内の区切りをマークする--separator=a
ことを定義します。a
newline
これは正しいですか?
私はこれを他の文字列やもっと多くの入力で試してみましたが、かなり混乱した状態になりました。他のオプションはすべて正常に動作すると思います。私が使用した場合、tac --before
最初に 1 行よりも 5 行ほどの空白行が表示されますが、その後はこれくらいで済むはずですよね?
答え1
tac
主に設計されているケース、つまりセパレータがレコード ターミネータである場合、つまりセパレータが最後のレコードの後に表示される場合、の方が理解しやすくなります。レコード (各ターミネータを含む) は逆の順序で印刷されます。
$ echo -n fooabara | tac -s a; echo
rabafooa
入力は 3 つのレコード ( foo
、b
およびr
) で構成され、各レコードの後にセパレータ が続きます。a
出力は 3 つのレコード ( r
、b
およびfoo
) で構成され、各レコードの後にセパレータ が続きますa
。
最後のレコードがレコード ターミネータで終わらない場合は、レコード セパレータなしで最初に印刷されます。
$ echo -n fooabar | tac -s a; echo
rbafooa
最後のレコードr
の末尾に区切り文字がなかったため、最後のb
レコードは、間に区切り文字が入らない状態で最後から 2 番目のレコードと連結されます。
改行があるため、入力が少しわかりにくくなっています。改行の代わりにカンマを使用して見てみましょう。
$ 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]+
) とオプションのマイナス記号のシーケンス ( -*
) が続きます。各レコードの行の順序とそのヘッダー行が保持されていることがわかります。
私はtac
、Twitter などのフィード アプリケーションで使用されるように、ログ ファイルのエントリを逆順に表示するためにこの方法を使用します。たとえば、最後の 2 つのレコードのみを逆順に印刷するには、次のようにします。
tac --before --regex --separator=^---[0-9]+-*$ example \
| awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'