スペースを改行してからsedを再度呼び出す必要があるのはなぜですか?

スペースを改行してからsedを再度呼び出す必要があるのはなぜですか?

与えられたファイルに含まれるすべてのバイトを8進形式でそれぞれ1行にリストしたいと思います。

これが機能する理由:

#!/bin/sh --

newline='
'

od -v -A n -t o1 -- /tmp/file | \
sed -e "s/ /\\${newline}/g" | \
sed -e '/^$/d'

代わりに:

#!/bin/sh --

newline='
'

od -v -A n -t o1 -- /tmp/file | \
sed -e "s/ /\\${newline}/g" -e '/^$/d'

タスクを完了するにはなぜsedを2回呼び出す必要があるのですか?

ちなみに、追加処理のない出力はod次のとおりです。

         047 124 167 141 163 040 142 162 151 154 154 151 147 054 040 141
         156 144 040 164 150 145 040 163 154 151 164 150 171 040 164 157
         166 145 163 012 011 104 151 144 040 147 171 162 145 040 141 156
         144 040 147 151 155 142 154 145 040 151 156 040 164 150 145 040
         167 141 142 145 072 012 101 154 154 040 155 151 155 163 171 040
         167 145 162 145 040 164 150 145 040 142 157 162 157 147 157 166
         145 163 054 012 011 101 156 144 040 164 150 145 040 155 157 155
         145 040 162 141 164 150 163 040 157 165 164 147 162 141 142 145
         056 012

ベストアンサー1

sed式はパターン空間全体で動作します。ループの開始時に行がパターン空間に読み込まれ、sed与えられた各式がそのデータに適用されます。

コードの2番目のバリエーションでは、置換を介してパターン空間に改行文字を挿入します。 2番目の式は、/^$/dパターン空間の各行ではなく、全パターン空間で動作し続けます。つまり、パターンが一致せず(バッファが空でないため)、パターン空間が一致しません。削除されました。/^$/dに変更すると、s/\n\{2,\}//g2つ以上の連続した改行が削除されます(これにより、出力に空白行が生成されます)。会議もう職場にいます。

sedこれは、2番目のバリアントが最初の出力を読み取るコードの最初のバリエーションとは対照的ですsed。この場合、2番目はsed生成された各行を読み取ります。個別に、空の項目を削除します。

sed簡単に言うと、パターン空間に改行を追加しても、生成された各行は、残りの式への別々の入力として再度考慮されません。


代替ソリューション:

od -v -A n -t o1 -- /tmp/file |
sed -e 's/ \{2,\}//g' -e 'y/ /\n/'

最初のsed式はs/ \{2,\}//g2つ以上の連続したスペースを削除し、2番目の式は残りのスペースを改行文字に変換します(POSIXでも\nコマンドが受け入れます)。ysed

または、残りのスペースを改行に変換する前に、サイドスペースをすべて削除できます。

od -v -A n -t o1 -- /tmp/file |
sed -e 's/^ *//' -e '$s/ *$//' -e 'y/ /\n/'

(出力の最後の行にのみod末尾のスペースがある可能性があるため、$これを2番目の式のアドレスとして使用しました。)

または、次のコマンドを使用する方が簡単ですawk

od -v -A n -t o1 -- /tmp/file |
awk '{ for (i = 1; i <= NF; ++i) print $i }'

おすすめ記事