N行ごとに改行文字を削除します


16

テキストを処理するには、2行ごとに改行文字を削除する必要があります。

サンプルテキスト:

this is line one
and this is line two
the third and the
fourth must be pasted too

望ましい出力:

this is line one and this is line two
the third and the fourth must be pasted too

whileループを試しましたが、whileループは悪い習慣です。trまたは他のコマンドを使用して実行できますか?


4
タイトルには「N行ごと」とありますが、質問と例では「2行ごと」です。ほとんどの答えはN = 2でのみ機能します。すべてのNで機能するものをお探しですか?
-JigglyNaga

それが鍵です。誰もが2行で答えましたが、N = 3またはN = 4を使用する必要があります
jomaweb

回答:


24

paste(同様の標準POSIXシンプルユーティリティtr)もそのためのツールです。

サンプルのように単に削除するのではなく、これらの改行文字をスペースに置き換えると仮定します。

paste -d ' ' - - < file

または:

paste -sd ' \n' file

本当に削除したい場合は' '、と置き換え'\0'ます。

3つのうち2つを置き換えるには:

paste -sd '  \n' file

2つ目から3つのうち1つ:

paste -sd '\n \n' file

等々。

もう1つの良い点pasteは、行が終了していないことです。たとえば、ファイル内のすべての改行を削除する場合(tr -d '\n' < fileまたはのようにtr '\n' ' ' < file)、行は改行文字で終了する必要があるため、行はまったくありません。そのpasteため、有効なテキストを得るために必要な末尾の改行文字を追加する(paste -sd '\0' fileまたはpaste -sd ' ' file)などの代わりに、一般的に使用する方が適切です。


11

最新のGNU sedを使用

sed -rz 's/\n([^\n]*\n)/ \1/g' sample.text

そしてawk

awk '{getline line2;print $0, line2}' sample.text

3
そのsedアプローチは、ファイル全体をメモリに丸lurみし(NULバイトが含まれていない場合)、高価な正規表現の置換を行うことを意味します。標準的なsed 'N;s/\n/ /'アプローチに勝る利点はありません。
ステファンシャゼラス

6

sed以下に示すように、これに使用します。

SHW@SHW:/tmp $ cat a
this is line one
and this is line two
the third and the
fourth must be pasted too

SHW@SHW:/tmp $ sed 'N;s/\n/ /' a -i

SHW@SHW:/tmp $ cat a
this is line one and this is line two
the third and the fourth must be pasted too

4

別の方法は使用することxargsです:

$ < txt xargs -d '\n' -n 2 echo
this is line one and this is line two
the third and the fourth must be pasted too

どこ

$ cat txt
this is line one
and this is line two
the third and the
fourth must be pasted too

ただし、echoプロセスは各行ごとに実行されるため、このソリューションは非常に過剰です。したがって、おもちゃの例に加えて、awk / sedなどに基づくソリューションが推奨されます。


1
あなたによってecho実装、あなたはまた、バックスラッシュ文字で始まるいくつかのラインに問題があるでしょう-(のような--helpもしくは-neneGNUとをecho)。また、これ-dはGNU拡張機能であることに注意してください。
ステファンシャゼル

での問題を回避するにはecho、これを使用できます< txt xargs -d '\n' -n 2 printf -- '%s %s\n'
。– nyuszika7h

4

これは、実際にはvimで非常に簡単です。すべての行を結合Jするには、%normコマンドを使用してから、コマンドを使用してすべての行に同時に適用します。例えば

:%norm J<CR>

(念のため、vimに慣れていない場合は、<CR>入力するだけです)

これは、任意の数の行を結合するためにも機能します。たとえば、10行ごとに結合するには

:%norm 9J<CR>

vimに不満があり、インタラクティブテキストエディターではなくコマンドラインツールとして使用したい場合は、次のようにします。

vim myfile -c '%norm J' -c 'wq'

この答えを改善するために私ができることを説明するのをダウンボッターは気にしますか?
DJMcMayhem

3
$ awk '{printf "%s%s",$0,(NR%2?" ":"\n")}' sample.txt
this is line one and this is line two
the third and the fourth must be pasted too

これ$0により、各行が出力され、その後に行番号NRが奇数か偶数かに応じてスペースまたは改行が出力されます。

NR%2?" ":"\n"は三項ステートメントです。NR%2行番号が奇数の場合、式はtrue(非ゼロ)と評価されます。この場合、3項式はスペースを返します。false(ゼロ)と評価された場合、改行が返されます。

代替案

コメントでコスタスが示唆したように:

$ awk '{ORS=(NR%2?" ":RS)}1' sample.txt
this is line one and this is line two
the third and the fourth must be pasted too

ここでは、三項ステートメントNR%2?" ":RSを使用して、スペースまたは入力レコード区切り文字(RS、default = newline)を返します。この値は、出力レコードセパレーターに割り当てられORSます。1コマンドの最後には、印刷レコード用のawkの不可解な速記です。


()括弧とprintf;の後のスペースの3文字を保存できます
-maxschlepzig

1
三元?ああ!'NR%2{printf("%s ",$0);next}1'
コスタス

maxschlepzigの答え:三元声明'{ORS=(NR%2?" ":RS)}1'
コスタス

@Costas私はそれが好きです。ORSソリューションで更新された回答。
ジョン1024

2

一般的なソリューション、5必要な行数に置き換えます

$ # eof to ensure last line has newline ending
$ seq 16 | perl -pe 's/\n/ / if ++$i%5 && !eof'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16

$ # or just use pr
$ seq 16 | pr -5ats' '
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16

1

awkこれに使用できます:

$ awk '{c="\n"} NR%2 {c=" "} { printf("%s%s", $0, c) } ' txt

以下を生成します。

this is line one and this is line two
the third and the fourth must be pasted too

どこ:

$ cat txt
this is line one
and this is line two
the third and the
fourth must be pasted too

awkアクションは各ライン、特別な変数のために実行される$0参照電流線は、NR現在の行番号(1から始まる)されます。2番目のアクションはNR%2、モジュロ演算である式によって保護されます。したがって、c=" "NR%2trueの場合、つまり奇数行番号の場合にのみ実行されます。

awk構文は次のようにCですが、いくつかの要素は、いくつかの状況ではオプションである-例えばセミコロン。


あなたのc変数があるORS'NR%2{ORS=" "}1;{ORS=RS}'
コスタス

0

を使用してed

$ cat text
this is line one
and this is line two
the third and the
fourth must be pasted too
this is line one
and this is line two
the third and the
fourth must be pasted too

$ ed text <<'END_ED'
g/./s/$/ /\
j
w text.new
END_ED
164
164

$ cat text.new
this is line one and this is line two
the third and the fourth must be pasted too
this is line one and this is line two
the third and the fourth must be pasted too

ed編集コマンドは、各行(のためになりますg与えられた正規表現にマッチするすべての行にコマンドを編集するセットを適用)、末尾にスペース文字を追加し、次の行でそれに参加します。次に、結果のテキストをというファイルに書き込みますtext.new


0

Rubyで。

n行の各ブロックが結合されると仮定します。仮定n = 3、入力ファイルがある'infile'との結果がファイルに書き込まれます'outfile'

ファイルを作成する

Ruby -e "File.write 'infile', <<_
> Line 1
> Line 2
> Line 3
> Line 4
> Line 5
> Line 6
> Line 7
> _"

ファイルの内容を確認します

ruby -e "p File.read 'infile'"
  # "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"

改行を削除してファイルに書き込む

ruby -e "File.write 'outfile', File.readlines('infile').
  each_with_index { |line,i| line.chomp! unless (i+1)%3==0 }"

内容を確認

ruby -e "puts File.read 'outfile'"
  # ["Line 1", "Line 2", "Line 3\n", "Line 4", "Line 5", "Line 6\n", "Line 7"]

1
良いもの。理論的にrubyは、U&Lではトピック外です。しかし、コマンドラインからを使用して使用しruby -eているため、トピックに十分対応できます。
grochmal
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.