मैं गलत स्थानों पर टूटी लाइनों को कैसे ठीक कर सकता हूं?


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
LaTeX? समस्या यह है कि आप वास्तव में उचित वाक्य को तोड़ने के लिए नियम नहीं बताते हैं। क्या आप एक ही लाइन पर एंड-ऑफ-द-वाक्य विराम चिह्न सहित सब कुछ करना चाहते हैं? लेकिन क्या होगा यदि आपके पास एक लंबी सजा है और यह आपके डिस्प्ले विंडो के किनारे से निकलता है?
jamesqf

1
मुझे आश्चर्य है कि आप वास्तव में क्या हल करने की कोशिश कर रहे हैं? शायद आपको मार्कडाउन फॉर्मेटिंग का उपयोग करना चाहिए?
वाइल्डकार्ड

@JeffSchaller अनुस्मारक के लिए धन्यवाद! मैं किसी तरह छूट गया था। :)

जवाबों:


7

प्रयत्न

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

कहाँ पे

  • $NF !~ /\.$/ मैच लाइन जहां अंतिम तत्व डॉट के साथ समाप्त नहीं होता है,
  • { printf "%s ",$0 इस रेखा को एक अनुगामी स्थान और कोई पंक्ति फ़ीड के साथ प्रिंट करें,
  • next ; } अगली पंक्ति लाएँ,
  • {print;} और इसे प्रिंट करें।

मुझे यकीन है कि एक sedविकल्प होगा।

नोट: यह एक डॉट में समाप्त होने वाली रेखा के साथ काम करेगा, हालांकि ऊपरी केस पत्र के साथ शुरू होने वाले वाक्यों में शर्त विलय नहीं होगी। देखें स्टीफन चेज़लस का जवाब।


यदि आपको चतुर (बहुत से नहीं)awk 'ORS=$NF~/\.$/?"\n":" "'
dave_thompson_085

10

के साथ awk:

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

यही है, प्रत्येक लाइन (ओआरएस खाली) के लिए रिकॉर्ड विभाजक को संलग्न न करें। लेकिन वर्तमान लाइन से पहले रिकॉर्ड विभाजक को प्रीपेन्ड करें यदि पहली पंक्ति पर नहीं है और वर्तमान लाइन लोअरकेस अक्षर से शुरू नहीं होती है। अन्यथा पहली पंक्ति को छोड़कर, एक स्थान वर्ण को पूर्व-निर्धारित करें।


जब मैं इसे चलाता हूं तो शब्दों के कुछ जोड़े संक्षिप्त हो जाते हैं। उदाहरण के लिए, And thisone issomehow, broken intomany.मुझे नहीं पता, awkलेकिन लाइनों के <space>अलावा के साथ शामिल होना चाहिए RS? या यह उपयोगकर्ता त्रुटि है?
बी लेयर

@ परत, अच्छी तरह से देखा, धन्यवाद। अब तय होना चाहिए।
स्टीफन चेज़लस

कोई दिक्कत नहीं है। हालांकि एक आश्चर्य की बात है कि 11 उत्थान कहां से आए। लोगों को यह मानने के लिए अच्छा होना चाहिए कि आप हमेशा सही हों। ;)
बी लेयर

4

पर्ल में:

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

तकनीकी रूप से आप "न्यूलाइन के बाद लोअर-केस लेटर" को "स्पेस और उस-लोअर-केस-लेटर" से बदलना चाहते थे, जो कि उपरोक्त पर्ल स्क्रिप्ट का मुख्य भाग है:

  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'(यह मानते हुए कि इनपुट में अशक्त वर्ण नहीं हैं)
Sundeep

3
@ संदीप, या perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'इसके लिए ASCII पत्रों तक सीमित नहीं है।
स्टीफन चेजलस 16

4

sedआप के साथ एक N;P;Dचक्र का उपयोग कर सकते हैं (ताकि हमेशा पैटर्न स्पेस में दो लाइनें हों और अगर नई लाइन के बाद पहला वर्ण कम हो तो एक स्थान के साथ नई रेखा को बदलें) और एक tस्था - इस तरह से प्रत्येक substeration के बाद आप चक्र को पुनः आरंभ करते हैं:

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

1
मुझे लगता है कि मैं देख रहा हूं कि यहां क्या हो रहा है, लेकिन एक विस्तारित जवाब हम में से उन लोगों की मदद करेगा जो बहुत बार sed छोरों और पैटर्न रिक्त स्थान का उपयोग नहीं करते हैं।
जो

@ जो - आपको "पैटर्न स्पेस का उपयोग बहुत बार नहीं" से क्या मतलब है ? जहां लगभग सभी ऑपरेशन होते हैं - होल्ड स्पेस एक "स्टोरेज स्पेस" है - आप डेटा के साथ कुछ भी नहीं कर सकते हैं, जबकि यह वहां है। वैसे भी, मैंने विस्तार से बताया है कि यहाँ एक N;P;Dचक्र कैसे काम करता है इसलिए मैं इसे दोबारा नहीं ले जाऊंगा। यहाँ अंतर यह है कि tस्थापन - यह जाँचने के लिए कि क्या कुछ प्रतिस्थापित किया गया था या नहीं - यदि परीक्षण सफल है तो हम स्क्रिप्ट के शीर्ष पर शाखा देते हैं, अन्यथा इसका अर्थ है कि कुछ भी प्रतिस्थापित नहीं किया गया और P;Dनिष्पादित किया गया। अगर यह अभी भी अस्पष्ट है तो मुझे बताएं।
don_crissti

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अधिक सुविधाओं और विकल्पों के साथ, अधिक सक्षम है ।

ध्यान दें कि प्रत्येक पैराग्राफ के बीच एक रिक्त रेखा होगी। पैराग्राफ को कम से कम एक खाली लाइन द्वारा एक दूसरे से अलग किया जाना चाहिए । रिक्त लाइनों के बिना, आपके पूरे इनपुट नमूने को एकल बहु-वाक्य पैरा के रूप में पुन: स्वरूपित किया जाता है, जैसे:

$ 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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.