間違った場所で壊れた行を修正するにはどうすればよいですか?


11

私のテキストファイルは次のようになります。

This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.

小文字で始まる行が続く行の末尾の改行文字を削除したい。

したがって、これは次のようになります。

This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

これどうやってするの?

編集:ここには本当に良い答えがいくつかありますが、私は最初に機能し最も早いものを受け入れることにしました。どうもありがとうございました!


1
ラテックス?問題は、適切な文分割のルールを実際に述べていないことです。文末句読点を含むすべてを1行に入れたいですか?しかし、長い文があり、それが表示ウィンドウの端からはみ出てしまうとどうなるでしょうか。
jamesqf 2017

1
あなたが本当に何を解決しようとしているのかしら?おそらく、マークダウン形式を使用する必要がありますか?
ワイルドカード2017

@JeffSchallerリマインダーありがとうございます!なんとか逃していた。:)

回答:


7

試す

awk '$NF !~ /\.$/ { printf "%s ",$0 ; next ; } {print;}' file

どこ

  • $NF !~ /\.$/ 最後の要素がドットで終わっていないマッチライン
  • { printf "%s ",$0 この行を末尾スペースを付けて改行なしで印刷します。
  • next ; } 次の行をフェッチし、
  • {print;} そしてそれを印刷します。

sedオプションがあると確信しています。

注:これはドットで終わる行で機能しますが、大文字で始まる文の条件はマージされません。StéphaneChazelasの回答を参照してください。


賢い人が好きな人(多くは好きではない)awk 'ORS=$NF~/\.$/?"\n":" "'
dave_thompson_085

10

awk

awk -v ORS= '{print (NR == 1 ? "" : /^[[:lower:]]/ ? " " : RS) $0}
             END {if (NR) print RS}'

つまり、各行にレコード区切り文字を追加しないでください(ORSは空です)。ただし、最初の行でなく、現在の行が小文字で始まっていない場合、現在の行の前にレコード区切り文字を追加します。それ以外の場合は、最初の行を除き、代わりにスペース文字を付加します。


これを実行すると、いくつかの単語のペアが連結されます。たとえば、And thisone issomehow, broken intomany.わかりませんがawk、行<space>に加えて行を結合する必要がありRSますか?それともこのユーザーエラーですか?
Bレイヤー

@BLayer、よく見つかる、ありがとう。今すぐ修正する必要があります。
ステファンChazelas

問題ない。11人の賛成投票がどこから来たのか不思議に思う人もいますが。人々があなたがいつも正しいと思い込んでいるのはいいことです。;)
Bレイヤー

4

Perlの場合:

#!/usr/bin/perl -w
use strict;
my $input = join("", <>);
$input =~ s/\n([a-z])/ $1/g;
print $input;

技術的には、「newlineの後に小文字が続く」を「space and-that-lower-case-letter」に置き換える必要がありました。これは、上記のperlスクリプトのコアが行うことです。

  1. 文字列への入力を読み込みますinput
  2. input変数を更新して、検索および置換操作の結果になります。
  3. 新しい値を出力します。

1
いいね!ワンライナーに変換さperl -0777 -pe 's/\n([a-z])/ $1/g'れ、GNU sedで同様に行うことができますsed -zE 's/\n([a-z])/ \1/g'(入力にnull文字がないと仮定)
Sundeep

3
@Sundeep、またはperl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'ASCII文字に限定されないようにするため。
ステファンChazelas

4

ではsed、あなたが使用することができN;P;D、サイクルを(そう常にとしては、パターンスペースに2つのラインを持っていると、改行の後の最初の文字が小文字の場合、次にスペースと改行置き換え)とtEST -それぞれの後にそのようにsあなたがサイクルを再起動ubstitutionを:

sed -e :t -e '$!N;/\n[[:lower:]]/s/\n/ /;tt' -e 'P;D' infile

1
私はここで何が起こっているかを理解していると思いますが、拡張された回答は、sedループとパターンスペースをあまり頻繁に使用しない私たちの助けになります。
Joe

@ジョー- 「パターンスペースをあまり頻繁に使用しない」とはどういう意味ですか?ここでほぼすべての操作が行われます。ホールドスペースは「ストレージスペース」です。データが存在している間は、データを操作することはできません。とにかく、ここでN;P;Dサイクルがどのように機能するかを詳細に説明しので、これ以上説明しません。ここでの違いは、t何かが置き換えられたかどうかを確認するための最も重要な点です。テストが成功した場合、スクリプトの先頭に分岐しP;Dます。それでも不明な点がある場合はお知らせください。
don_crissti 2017

3

sedおよびの使用fmt

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt
This is one sentence that is broken.

However this is a good one.

And this one is somehow, broken into many.

sedスクリプトは、大文字で始まるすべての行の前に改行を挿入します(入力の最初の行を除く)。 sedの出力は次にパイプされfmtて、結果の段落が再フォーマットされます。

またはpar、インストールされている場合に使用します。これは別の段落の書き直しですが、よりfmtも多くの機能とオプションを備えており、より機能的です。

各段落の間に空白行があることに注意してください。段落、少なくとも1つの空白行で互いに分離する必要があります。空白行がない場合、入力サンプル全体が単一のマルチセンテンス段落として再フォーマットされます。例:

$ fmt input.txt
This is one sentence that is broken.  However this is a good one.
And this one is somehow, broken into many.

再フォーマット後に空白行を削除する必要がある場合は、パイプラインをsedもう一度通過させます。ただし、これにより、元の入力に含まれていた可能性のあるすべての空白行が削除されます。例えば

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt | sed -e '/^$/d'
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

3

これを行う別の方法は次のとおりです。

perl -lpe '$\ = /\.$/ ? $/ : $"' data

ここで:$\=> ORS$/=> IRS= \n$"=space

perl -pe '$_ .= <>, eof or redo if s/[^.]\K\n/ /' data

sed -e '
   :a
      /\.$/!N
      s/\n/ /
   ta
' data

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.