मैंने PDF की एक बड़ी राशि (10GB) को स्क्रैप कर दिया है और उन्हें टेक्स्ट फ़ाइलों में बदल दिया है, लेकिन मूल PDF के प्रारूप के कारण, एक समस्या है:

कई शब्द जो रेखाओं के पार जाते हैं उनमें एक पानी का छींटा होता है जो कृत्रिम रूप से शब्द को तोड़ता है, जैसे:

enter image description here

आप देख सकते हैं कि ऐसा इसलिए हुआ क्योंकि मूल PDF फ़ाइलें टूट गई हैं:

enter image description here

.txt फ़ाइल के अंदर इस पैटर्न से मेल खाने वाले प्रत्येक शब्द उदाहरण को "जुड़ने" का सबसे साफ और तेज़ तरीका क्या होगा?

शायद किसी प्रकार की रेगेक्स खोज, जैसे किसी प्रकार के [a-z]\-\s \w के लिए (शब्द वर्ण के बाद डैश के बाद स्थान) काम करेगा? या किसी प्रकार का sed प्रतिस्थापन बेहतर काम करेगा?

वर्तमान में, मैं काम करने के लिए एक सेड रेगेक्स प्राप्त करने की कोशिश कर रहा हूं, लेकिन मुझे यकीन नहीं है कि चयनित टेक्स्ट को बदलने के लिए कैप्चर समूहों का उपयोग करने के लिए इसका अनुवाद कैसे किया जाए:

sed -n '\%\w\- [a-z]%p' Filename.txt

मेरा इनपुट टेक्स्ट इस तरह दिखेगा:

The dog rolled down the st- eep hill and pl- ayed outside.

और आउटपुट होगा:

The dog rolled down the steep hill and played outside.

आदर्श रूप से, अभिव्यक्ति एक नई पंक्ति द्वारा विभाजित शब्दों के लिए भी काम करेगी, जैसे:

The rule which provided for the consid-
eration of the resolution, was agreed to earlier by a

इसके लिए:

The rule which provided for the consideration 
of the resolution, was agreed to earlier by a
0
Harrison Cramer 17 नवम्बर 2020, 17:21

3 जवाब

सबसे बढ़िया उत्तर

यह sed में सीधा है:

sed -e ':a' -e '/-$/{N;s/-\n//;ba
}' -e 's/- //g' filename

यह मोटे तौर पर अनुवाद करता है "यदि रेखा एक डैश के साथ समाप्त होती है, तो अगली पंक्ति में भी पढ़ें (ताकि आपके पास बीच में एक कैरिज रिटर्न के साथ एक लाइन हो) फिर डैश और कैरिज रिटर्न को एक्साइज करें, और शुरुआत में वापस लूप करें यदि यह नई लाइन भी एक डैश के साथ समाप्त होती है। फिर - " के किसी भी उदाहरण को हटा दें।

2
Beta 17 नवम्बर 2020, 20:27

आप इस gnu-awk कोड का उपयोग कर सकते हैं:

cat file

The dog rolled down the st- eep hill and pl- ayed outside.
The rule which provided for the consid-
eration of the resolution, was agreed to earlier by a

फिर इस तरह awk का उपयोग करें:

awk 'p != "" {
   w = $1
   $1 = ""
   sub(/^[[:blank:]]+/, ORS)
   $0 = p w $0
   p = ""
}
{
   $0 = gensub(/([_[:alnum:]])-[[:blank:]]+([_[:alnum:]])/, "\\1\\2", "g")
}
/-$/ {
   p = $0
   sub(/-$/, "", p)
}
p == ""' file
The dog rolled down the steep hill and played outside.
The rule which provided for the consideration
of the resolution, was agreed to earlier by a

यदि आप perl पर विचार कर सकते हैं तो यह आपके लिए भी काम कर सकता है:

फिर उपयोग करें:

perl -0777 -pe 's/(\w)-\h+(\w)/$1$2/g; s/(\w)-\R(\w+)\s+/$1$2\n/g' file
2
anubhava 17 नवम्बर 2020, 18:31

आप बस बैकस्लैश-कोष्ठक जोड़ते हैं (या -r या -E विकल्प का उपयोग करें यदि उपलब्ध हो तो कोष्ठक को कैप्चर करने से पहले बैकस्लैश लगाने की आवश्यकता को दूर करने के लिए) और \1 के साथ मिलान किए गए टेक्स्ट को याद करें। पहला कैप्चरिंग कोष्ठक, \2 दूसरे के लिए, आदि।

sed 's/\(\w\)\- \([a-z]\)/\1\2/g' Filename.txt

\w एस्केप मानक sed नहीं है, लेकिन अगर यह आपके लिए काम करता है, तो बेझिझक इसका इस्तेमाल करें। अन्यथा, [A-Za-z0-9_@] या जो भी आप "शब्द वर्ण" कहना चाहते हैं, उसके साथ प्रतिस्थापित करना आसान है।

मैं अनुमान लगा रहा हूं कि सभी मैच हाइफेनेटेड शब्द नहीं होंगे, इसलिए शायद परिणाम को स्पेलिंग चेकर के माध्यम से चलाएं या यह सत्यापित करने के लिए कि परिणाम एक अंग्रेजी शब्द है या नहीं। (हालांकि, मैं शायद इसके लिए पाइथन जैसी अधिक सक्षम स्क्रिप्टिंग भाषा में स्विच करूंगा।)

0
tripleee 17 नवम्बर 2020, 18:15