fmt
を使用した回答 包むようです アンラップではなくテキスト
一般に、これは難しい問題になる可能性があります。たとえば、意図的に早く終了するテキストの隣接行 (箇条書きなど) と自由に流れるテキストの隣接行を区別するには、何らかのコンテキストが必要になる場合があります。ハイフンでつながれた単語が複数行にまたがって分割されていることと、単語が分割されていることを区別することも困難です。
ただし、散文の一般的な形式は、単一の空の改行で区切られた段落を形成するテキストの隣接する折り返し行です。
これは、次のやや複雑な sed one liner を使用してアンラップできます:
sed -n '/.+/ H; /^$/ { x; s/\n/ /g; s/$/\n/ ; p}'
または、特にいくつかの特殊なケースを処理する場合は、小さな python スクリプトを好むかもしれません:
import sys
paragraph = []
for line in sys.stdin:
line = line.strip()
if line:
paragraph.append(line)
else:
print ' '.join(paragraph).replace(' ', ' ')
paragraph = []
if paragraph:
print ' '.join(paragraph).replace(' ', ' ')
特別な大文字と小文字を追加していることに気付いた場合は、改行されたテキストの元を見つけて、改行されていない形式で取得することをお勧めします。
Att Righ が言ったように、特別な場合…
fortune
からの出力を「アンラップ」したかったので、この質問を見つけました フォーチュン クッキーの中には 78 文字でラップされているものもあれば、77、76、さらには 75 文字でラップされているものもあります。
私のスクリプトは、改行が意図的に挿入されたのか、それとも長さの制限のために挿入されたのかを判断しようとします。次の行の最初の単語も含まれます)。便利な副作用として、次の行が空白で始まる場合、最初の単語 (空白で区切られたもの) は空の文字列になるため、インデントされた段落がその上の行にマージされることはありません。
#!/usr/bin/python3
import sys
import fileinput
lines = list(fileinput.input())
lines = [l.strip('\r\n') for l in lines]
for i, l in enumerate(lines):
# We need to account for 8-char-wide tabulators when calculating our line
# length, but still want to print the original \t characters verbatim
sanitized_line = l.replace('\t', ' '*8)
# Is there a next line?
if i+1 < len(lines):
sanitized_next_line = lines[i+1].replace('\t', ' '*8)
else:
sanitized_next_line = ''
next_line_first_word = sanitized_next_line.split(' ', 1)[0]
if next_line_first_word != '':
extended_line = sanitized_line + ' ' + next_line_first_word
else:
extended_line = sanitized_line
if len(sanitized_line) <= 78 and len(extended_line) > 74:
# This line was wrapped due to 78-char limit => unwrap it!
sys.stdout.write(l + ' ')
else:
sys.stdout.write(l + '\n')