POSIX sedを使用して行をリンクしようとしています。
--posixなしでGNU sedを使用すると、期待どおりに機能します。
$ sed ':a; N; s/\n//; b a' <<< $'a\nb\nc'
abc
しかし、--posixを使用すると、どの出力も得られません。
なぜそんなことですか?それ以外の場合はどうすればよいですか?
答え1
これは仕事ですpaste
:
printf '%s\n' a b c | paste -sd '\0' -
(いいえ、これはNULで結合するのではなく、POSIXが要求するように区切りなしで結合することです。一部のpaste
実装ではこれをサポートしますpaste -sd '' -
が、これは標準でも移植可能でもありません。)
ビジーボックスの実装を除いて、入力が空の場合は空白行が出力として生成されます(残念ながら、過去のバグ/バグ機能はPOSIX仕様に刻まれています)。
POSIXの使用sed
:
sed -e :a -e '$!{N;ba' -e '}' -e 's/\n//g'
または:
sed '
:a
$!{
N
ba
}
s/\n//g'
b
、:
およびコマンド}
の後に他のコマンドは続くことはできません。 POSIX 仕様の以前のバージョンでは名前付きラベルへの分岐がb a;s/a/b/
必要でしたが、最新バージョンの仕様では GNU 動作を許可するように指定されていません。次のコマンドは、後続の式または別の行になければなりません。b
a;s/a/b/
sed
POSIXでは、N
パターンスペースを印刷せずに最後の行で終了する必要があります。 GNUは、sed
変数が環境に存在する場合やオプションが使用されている場合など、POSIXモードでのみこれを行います。これがその理由を説明します。POSIXLY_CORRECT
--posix
--posix
さらに、POSIXは少なくとも8192バイトのパターンスペースサイズを保証します。この方法は非常に小さなファイルにのみ移植できます。paste
サイズ制限はなく、sed
この方法とは異なり、印刷する前にファイル全体をメモリにロードする必要はありません。
もう一つの方法はですtr -d '\n'
。ただし、paste
/とは異なり、sed
出力に区別されていない行が生成されます(上記の例abc
ではなく出力)。abc\n
とにかく、<<<
演算子(zsh
現在他のシェルでサポートされています)、$'...'
ksh93演算子(現在の他のほとんどのPOSIX様シェルでサポートされています)、POSIX演算子でもありませんsh
(後者が次に追加される可能性があります)。標準改訂)したがって、sh
POSIXスクリプトで使用しないでください。
答え2
すべてのUNIXシステムのすべてのシェルにあるすべてのawkの場合、すべてのサイズの入力ファイルについて(入力ファイルが1つの大きなテキスト行であり、メモリに収まらないスペースを含まない限り):
$ printf '%s\n' a b c | awk -v ORS= '1; END{if (NR) print RS}'
abc