root@u1804:~# sed --version
sed (GNU sed) 4.5
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email protected]>.
root@u1804:~#
私はsedに初めて触れ、私が理解した内容に基づいて次のようなsedワークフローを作成しました(間違いを見つけたら修正してください)。
したがって、パターン空間のデフォルトの自動印刷には常に末尾に改行文字が含まれているようです。私の質問にはp
改行も含まれていますか?次の例があります。
root@u1804:~# seq 3 | sed -rn 'p'
1
2
3
root@u1804:
ここで、各数字の末尾にある改行文字は sed 自体によって追加されます(図「パターン空間に改行文字を再追加する」を参照)。したがって、p
改行文字が追加されていないようです。ただし、以下の例を参照してください。
root@u1804:~# seq 3 | sed -rn 'x;p;x;p'
1
2
3
root@u1804:~#
ここで、x
パターンスペースはホールドスペースと交換され、パターンスペースが空になります。p
パターンスペース(何も含まない)に適用すると、何も印刷されません。しかし、結果によると、p
ここに改行文字が印刷されているようです。私が見ると、これは一貫性のない行動のようです。誰でもこれを説明できますか?
答え1
主な質問に答えるには:
GNU は、入力行に終了文字が欠けていない限り、コマンドを実行する際に文字を追加しますsed
(以下の行の説明を参照)。<newline>
p
<newline>
私が知る限り、sed
フラグp
とその自動印刷機能はパターンスペースを出力するために同じロジックを実装します。<newline>
末尾の文字が削除された場合は再度追加し、末尾の文字が削除された場合は再度追加します。そうでなければそうではありません。
例:
$ printf '%s\n%s' '4' '5' | sed ';' | hexdump -C # auto-print
00000000 34 0a 35 |4.5|
00000003
$ printf '%s\n%s' '4' '5' | sed -n 'p;' | hexdump -C # no auto-print; p flag
00000000 34 0a 35 |4.5|
00000003
<newline>
どちらの場合も、文字のない入力行()の場合、出力に文字()はありません。0a
チャート情報:
「パターン空間に改行文字を追加する」は、文字が配置されていないため正確では<newline>
ない可能性があります。存在するパターンスペース1.また、このステップはオプションとは関係ありませんが、-n
チャートは作成しません。間違った; 代わりに「印刷モード空間」にマージする必要があります。
しかし、文書の明確性が不足していることに同意します。
1あなたが引用した文あなた自身の答えに、「パターン空間の内容が出力ストリームに印刷され、末尾の改行文字が削除されると再び追加される」とは、パターン空間ではなくストリームに追加されることを意味する<newline>
。もちろん、パターン空間が素早くクリアされるため、これは非常にマイナーな問題です。
フラグに関連するテストについてx
:
内部的には、パターンスペースと予約スペースの両方が構造ですが、「<newline>
私の後続の文字は削除されましたか?」もその1つです。我々はそれを呼ぶ噛んだsed
(ところで、ソースコードに名前が付けられています)。
パターン空間は読み出しラインと対応するラインで埋められる。噛んだ属性は、行の終了方法によって異なります。true
つまり、文字で終わる場合<newline>
、false
そうでない場合です。一方、保持空間は空になって初期化され、噛んだプロパティがちょうどに設定されましたtrue
。
したがって、パターンスペースを交換し、スペースを予約し、元々はスペアであり、今ではパターンになったものを印刷すると<newline>
文字が印刷されます。
例 - 次のコマンドは同じ出力を持ちます。
$ printf '\n' | sed -n 'p;' | hexdump -C # input is only a <newline>
00000000 0a |.|
00000001
$ printf '%s' '5' | sed -n 'x;p;' | hexdump -C # input has no <newline>
00000000 0a |.|
00000001
sed
(コードを少し見ているので、正確ではない可能性があります。)
行について(説明はコメントで始まりますあなたの答え):
言うまでもない、ワイヤー終了文字がないというのは<newline>
問題のある概念です。引用するPOSIX:
3.206ライン
<newline>
ゼロ個以上の非文字と終了文字のシーケンスです<newline>
。
また、POSIXテキストファイルを定義します。
3.403 テキストファイル
ゼロ行以上の文字を含むファイル。 ...
ついに、POSIX(太い鉱山)情報sed
:
説明する
このsed
ユーティリティは1つ以上のストリームエディタです。テキストファイル、編集コマンドのスクリプトに基づいて編集変更を実行し、結果を標準出力に書き込みます。 ...
牛に似た一種の栄養sed
しかし、入力を定義するにはあまり厳しくないようです。
sed
ストリームエディタです。ストリームエディタは、入力ストリーム(ファイルまたはパイプの入力)で基本的なテキスト変換を実行するために使用されます。 ...
sed
したがって、最初の文に関してGNUの場合、パターン空間に読み込まれる内容が必ずしもよく構成されたテキスト行ではないことを考慮する必要があります。
答え2
答え3
GNU sedでは:p
コマンドはソーステキストにある場合にのみ末尾の改行を追加します(パターンスペースに配置されたときに入力から削除されます)返品同じストリームに別のテキストを印刷する場合は、前に新しい行を追加します。
入力にのみ末尾の改行がありません。最後ワイヤー。
$ printf 'abc' | od -An -c
a b c # no newline.
$ printf 'abc' | sed '' | od -An -c
a b c # also no newline.
$ printf 'abc' | sed -n 'p' | od -An -c
a b c # still no newline.
$ printf 'abc' | sed -n 'p;p' | od -An -c
a b c \n a b c # leading newline added.
新しい行が生成される最後の行だけを印刷してください。ただソースファイルの最後の行にすでに改行文字がある場合:
$ printf 'abc\ndef' | sed -n '$p' | od -An -c
d e f
情報sedから:
-----------脚注----------
(1)実際に 'sed'が改行を終了せずに1行を印刷してから、同じ出力ストリームにもう一度テキストを送信すると、まだ行方不明の改行を印刷します。これは「最も予想外の驚き」を提供します。 「sed -np」のようなコマンドを「cat」とまったく同じにしないでください。
他のsedバージョンが追加されることがあります。続く改行および/または警告を発行します。