web-dev-qa-db-ja.com

sedのみを削除します\ n sed '='コマンドによって提供されます

私は使用してファイルを作成しました:

printf 'this is \n not is \n is is \n this biz' > file2

すべての\ n(改行)を削除しようとすると、sed自身の挿入された番号の改行のみが削除されます

sed  '=' file2 | sed 'N; s/\n/ /' 

出力は次のとおりです。

 1 this is 
 2  not is 
 3  is is 
 4  this biz

そして私が期待していたものではありません:

1 this is  2  not is  3  is is  4  this biz

迷っています。

7
Linux Newbie

2番目のsedスクリプト、

N
s/\n/ /

は1行を読み取るため、期待どおりに動作しません。次に、Nコマンドによって挿入された埋め込み改行を次の行に追加し、その改行をスペース(および出力)に置き換えます。次の行を読み取る場合、最初の2行の結果は破棄されます。

代わりに、ホールドスペースを使用する必要がありました。

H;            # append to hold space with a '\n' embedded
              # for the last line:
${
    x;        # swap in the hold space
    s/\n//;   # delete the first newline (from the H command on the very first line of input)
    y/\n/ /;  # replace all other newlines with spaces
    p;        # print result
}

このスクリプトは入力の各行に対して1回実行され、最後の行に到達するまでホールドスペースでデータを収集します。最後の行では、収集したデータを処理して出力します。

これはsed -nで実行します。

$ sed '=' <file2 | sed -n 'H; ${ x; s/\n//; y/\n/ /; p; }'
1 this is  2  not is  3  is is  4  this biz

(入力の最後に改行がないため、出力の最後に改行はありません)。

あるいは、明示的なループでNを使用できます。ここでの秘訣は、結果を出力する準備ができるまでスクリプトの最後に到達しないことです。

:top;     # define label 'top'
N;        # append next line with a '\n' embedded
$!btop;   # if not at end, branch to 'top'
y/\n/ /;  # replace all newlines with spaces
          # (implicit print)

このスクリプトは(最後まで)1回だけ実行され、データ自体の読み取りを管理しますが、前のスクリプトはsedの組み込みの読み取りループ(これは)によってデータを供給されていました読み取った各行のパターンスペースを置き換えます。これは問題でした)。ホールドスペースではなくパターンスペースを使用してデータを収集し、最後の行が読み取られたときにデータを処理します。

コマンドラインで:

$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'

(上記と同じ出力)

7
Kusalananda

GNU sedの場合、これを試してください

$ sed -z 's/\n/ /g' file2
this is   not is   is is   this biz
$

trも同様にうまく機能します。

$ tr '\n' ' ' <file2
this is   not is   is is   this biz
$
4
steve

これは基本的にsedが行指向であるためです。何が起こるか

  • sedは最初の行1をパターンスペースにロードします
  • Nコマンドは次の行をロードし、\nで区切ってパターンスペースに追加し、1\nthis is
  • \nをスペースで置き換え、1 this is

これで完了です。パターンスペースが印刷され、残りの(ペアの)ラインのそれぞれについて手順が繰り返されます。

3
steeldriver

使用したコマンドはpairsの行のみを処理します。
最初の行は行番号です(=コマンド)。
2行目は最初の行に追加され、1つの改行が削除されて印刷されます。
次に、次のpair行が均等に処理されます。

all行を処理する唯一の方法は、最後の行までそれらを蓄積することです。
その時点で、すべての改行を消去/スペースに変換できました:

$ sed '=' file | sed ':start;N;$bend;bstart;:end;y/\n/ /'
1 this is  2  not is  3  is is  4  this biz

短い行(ただし、この非常に短いファイルでは問題にならない遅い行も)は次のとおりです。

sed ':1;N;s/\n/ /;t1'

上記の両方のソリューションは、ファイル全体をメモリに保存することに注意してください。

ただし、もちろん、trはこのジョブに適したツールです。

$ sed '=' file | tr '\n' ' '

または、paste(末尾の改行を保持する):

$ sed '=' file | paste -sd ' '
1 this is  2  not is  3  is is  4  this biz
0
Isaac

以下のコマンドで試してみましたが、うまくいきました

inputfile

this is
 not is
 is is

コマンド:

cat inputfile|sed "="| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"

出力

1 this is  2  not is  3  is is  4  this biz
0