একটি স্ক্রিপ্ট যা পাঠ্যের অক্ষরের মধ্যে অতিরিক্ত স্থান মুছে দেয়


12

আমার কাছে একটি টেক্সট ডকুমেন্ট রয়েছে যাতে পাঠ্যের ভার থাকে যা প্রতিটি অক্ষরের পরে অতিরিক্ত স্থান যুক্ত করে দেয়!

উদাহরণ:

T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t

দৃশ্যরূপে:

T␣h␣e␣␣b␣o␣o␣k␣␣a␣l␣s␣o␣␣h␣a␣s␣␣a␣n␣␣a␣n␣a␣l␣y␣t␣i ␣c␣a␣l␣␣p␣u␣r␣p␣o␣s␣e␣␣w␣h␣i␣c␣h␣␣i␣s␣␣m␣o␣r␣e␣␣i␣ m␣p␣o␣r␣t␣a␣n␣t ...

নোট করুন যে প্রতিটি বর্ণের পরে একটি অতিরিক্ত স্থান রয়েছে, সুতরাং পর পরের শব্দের মধ্যে দুটি স্থান রয়েছে।

এমন কোনও উপায় আছে যা আমি পেতে awkবা sedঅতিরিক্ত স্থানগুলি মুছতে পারি? (দুর্ভাগ্যক্রমে এই পাঠ্য নথিটি বিশাল এবং ম্যানুয়ালি যেতে খুব দীর্ঘ সময় লাগবে))  আমি প্রশংসা করি যে এটি সম্ভবত একটি সহজ বাশ স্ক্রিপ্টের সাথে সমাধান করার জন্য আরও জটিল সমস্যা কারণ এখানে কিছু ধরণের পাঠ্য স্বীকৃতিও প্রয়োজন।

আমি কীভাবে এই সমস্যার কাছে যেতে পারি?


2
সমস্ত স্থানকে কোনও কিছুই দিয়ে প্রতিস্থাপন করা তুচ্ছ বিষয় .. তবে আমি মনে করি আপনি শব্দগুলি আলাদা করতে চান?
সন্দীপ

প্রাক্তন জন্য:echo 't h i s i s a n e x a m p l e' | sed 's/ //g'
সন্দীপ

1
এটি অক্ষরের মধ্যে ফাঁকা স্থানগুলিতে সীমাবদ্ধ করে না । ( উদাহরণস্বরূপ অঙ্কগুলি এবং বিরামচিহ্নগুলি অক্ষর নয় )। আপনি একটি লুপ দিয়ে সেড এ এটি করতে পারেন। এটি সম্ভবত একটি সদৃশও।
টমাস ডিকি

1
কেবলমাত্র অক্ষরের মধ্যে সীমাবদ্ধ করতে:echo 'T h i s ; i s .a n 9 8 e x a m p l e' | perl -pe 's/[a-z]\K (?=[a-z])//ig'
সন্দীপ

4
@ জুলিপেল্টিয়ার: মূল সংশোধনের উত্সটি দেখায় যে শব্দের মধ্যে স্পেসগুলি দ্বিগুণ করা হয়েছিল। আপনি কেন তাদের সম্পাদনায় এগুলি দ্বিগুণ করলেন?
এল'েন্দিয়া স্টারম্যান

উত্তর:


16

নিম্নলিখিত রেজেক্স স্পেসের যে কোনও স্ট্রিংয়ের প্রথম স্থানটি সরিয়ে ফেলবে। যে কাজ করা উচিত।

s/ ( *)/\1/g

সুতরাং যেমন কিছু:

perl -i -pe 's/ ( *)/\1/g' infile.txt

... infile.txt "স্থির" সংস্করণে প্রতিস্থাপন করবে।


@ ইটারডন আমি সাম্প্রতিক সময়ে লক্ষ্য করেছি যে লোকেদের পার্ল পাই স্ক্রিপ্টগুলি লিখতে বন্ধ করা হয়েছে perl -pie- যেমন আপনার সম্পাদনা দেখায়। এর যৌক্তিকতা কী? -পি সর্বদা আমার জন্য ভাল কাজ করেছে, এবং এটি একটি দুর্দান্ত স্মৃতিচক্র। কোনও বিন্দু দিয়ে শুরু হওয়া জিনিসগুলির পরিবর্তে, কোনও এক্সটেনশান হিসাবে অনুসরণ করে অন্যটির আচরণের পরিবর্তিত হয়েছে? তাদের এত অদ্ভুত কিছু ভাঙা অবাক লাগবে।
দেবী মরগান

1
হুহ, এটি কোনও মূর্খতা নয় যার সাথে আমি পরিচিত। পার্ল যতক্ষণ ব্যবহার করে আসছি ততক্ষণ এভাবেই ছিল -i। অন্যদিকে, আমি এটি কখনও লিনাক্স মেশিনে ব্যবহার করেছি এবং কয়েক বছরের বেশি সময় ধরে আমি এটি সম্পর্কে জানি না, সুতরাং এর পুরানো আচরণ সম্পর্কে আমি বলতে পারি না। আমার মেশিন যদিও, এই: perl -pie 's/a/b/' f, একটি ত্রুটি উৎপন্ন: Can't open perl script "s/o/A/": No such file or directoryperl -i -pe 's/o/A/' fপ্রত্যাশার মতো কাজ করার সময় । হ্যাঁ, eব্যাকআপ এক্সটেনশন হিসাবে নেওয়া হয়।
টেরডন

গোমরা মুখ. আহ, ভাল, সময় এগিয়ে চলেছে এবং এর ঠিক অর্থ হল আমার প্যারামিটার ক্রমটি পুনরুদ্ধার করা দরকার। আমার মস্তিষ্ককে স্কুইশি রাখে, আমার ধারণা। আমাকে জানাতে এবং আমার কোড ঠিক করার জন্য ধন্যবাদ!
দেউই মরগান

17

ব্যবহার করুন wordsegment, একটি খাঁটি-পাইথন শব্দ বিভাজন NLP প্যাকেজ:

$ pip install wordsegment
$ python2.7 -m wordsegment <<<"T h e b o o k a l s o h a s a n a n a l y t i c a l p u r p o s e w h i c h i s m o r e i m p o r t a n t"
the book also has an analytical purpose which is more important

1
শব্দগুলি বাদে আর কিছু না বললে এনএলপি ব্যবহার করা সম্ভবত সবচেয়ে কার্যকর সমাধান। এনএলপি বেশিরভাগ ক্ষেত্রে চেহারা-এগিয়ে অভিধানের চেয়ে আরও ভাল সম্পাদন করে।
গ্রোচামাল

13

ইনপুট শব্দের মধ্যে দ্বিগুণ স্থান অন্তর্ভুক্ত করে এই তথ্যের ভিত্তিতে একটি আরও সহজ সমাধান রয়েছে। আপনি কেবল ডাবল স্পেসগুলি অব্যবহৃত অক্ষরে বদলে ফেলুন, স্পেসগুলি সরিয়ে ফেলুন এবং অব্যবহৃত অক্ষরটিকে একটি জায়গায় ফিরিয়ে আনুন:

echo "T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t  " | sed 's/  /\-/g;s/ //g;s/\-/ /g'

... আউটপুট:

বইটির একটি বিশ্লেষণমূলক উদ্দেশ্যও রয়েছে যা আরও গুরুত্বপূর্ণ


5
একটি অর্থ "একটি অ-স্পেস চরিত্র প্রতিটি occurence প্রতিস্থাপন, শুধু সংশ্লিষ্ট অ স্থান অক্ষর দিয়ে একটি স্থান করে তারপরে" সঙ্গে একটি sed কমান্ড একই আছে:sed -e "s/\([^ ]\) /\1/g"
woodengod

3
এটি আসলেই একটি ভাল বিকল্প। এর ক্রেডিট পাওয়ার জন্য আপনার উত্তর হিসাবে এটি পোস্ট করা উচিত।
জুলি পেলেটিয়ার

10

পার্ল উদ্ধার!

আপনার একটি অভিধান প্রয়োজন, অর্থাত প্রতি লাইনে একটি শব্দ তালিকাভুক্ত একটি ফাইল। আমার সিস্টেমে এটি উপস্থিত রয়েছে /var/lib/dict/words, আমি একই ধরণের ফাইল /usr/share/dict/britishইত্যাদিও দেখেছি

প্রথমত, আপনি অভিধান থেকে সমস্ত শব্দ মনে রাখবেন। তারপরে, আপনি লাইন দ্বারা ইনপুট লাইনটি পড়েন এবং কোনও শব্দের সাথে অক্ষর যুক্ত করার চেষ্টা করেন। যদি এটি সম্ভব হয় তবে আপনি শব্দটি মনে রাখবেন এবং বাকী রেখাটি বিশ্লেষণ করার চেষ্টা করুন। আপনি যদি লাইনের শেষ প্রান্তে পৌঁছান, আপনি লাইনটি আউটপুট করেন।

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $words = '/var/lib/dict/words';
my %word;

sub analyze {
    my ($chars, $words, $pos) = @_;
    if ($pos == @$chars) {
        $_[3] = 1;  # Found.
        say "@$words";
        return
    }
    for my $to ($pos .. $#$chars) {
        my $try = join q(), @$chars[ $pos .. $to ];
        if (exists $word{$try}) {
            analyze($chars, [ @$words, $try ], $to + 1, $_[3]);
        }
    }
}


open my $WORDS, '<', $words or die $!;
undef @word{ map { chomp; lc $_ } <$WORDS> };

while (<>) {
    my @chars = map lc, /\S/g;
    analyze(\@chars, [], 0, my $found = 0);
    warn "Unknown: $_" unless $found;
}

আপনার ইনপুটটির জন্য, এটি আমার সিস্টেমে 4092 সম্ভাব্য পাঠ্য উত্পন্ন করে।


এর বাইরে ব্যবধানে সংস্করণের সাথে পরীক্ষা ব্যর্থ a cat a logঅর্থাতa c a t a l o g
Ctrl-Alt-delor

@রিচার্ড: ওবিওই, স্থির। তবে এটি এখন অনেকগুলি সম্ভাব্য উত্স তৈরি করে, একটি অক্ষরের শব্দ মুছে ফেলার চেষ্টা করুন।
চোরোবা

@richard আপনি এই সমস্যাটি একটি অ-নিরস্তাত্মক অ্যালগরিদমের সাহায্যে লড়াই করতে পারেন (উদাহরণস্বরূপ সমস্ত সম্ভাব্য পাঠক সংরক্ষণাগার রয়েছে) এবং এতে পার্সার প্রয়োগ করুন। তারপরে আপনি সর্বনিম্ন ত্রুটি গণনার সাথে সমস্ত 4000 সম্ভাব্য পাঠকে একক একটিতে ফিল্টার করতে পারেন।
bash0r

6

দ্রষ্টব্য: এই উত্তরটি (এখানে কয়েকজনের মতো এখানে) প্রশ্নের পূর্ববর্তী সংস্করণের উপর ভিত্তি করে যেখানে শব্দগুলি সীমিত করা হয়নি। নতুন সংস্করণটির তুচ্ছ উত্তর দেওয়া যেতে পারে ।

একটি ইনপুট যেমন:

T h e b o o k a l s o h a s a n a n a l y t i c a l p u r p o s e w h i c h i s m o r e i m p o r t a n t

আপনি চেষ্টা করতে পারেন:

 $ tr -d ' ' < file | grep -oiFf /usr/share/dict/words | paste -sd ' '
 The book also has ana na l y tic al purpose which ism ore important

এটি বাম থেকে ডানে প্রক্রিয়া করে এবং পরের পরে একটি দীর্ঘতম শব্দ খুঁজে পায়।

স্পষ্টতই, এখানে, এটি শব্দের সেরা নির্বাচন নয় কারণ সেই বাক্যটি কোনও অর্থবোধ করে না, তবে সঠিক শব্দটির সাথে সামনে আসতে, আপনাকে ব্যাকরণ বা পাঠ্যের অর্থ বুঝতে বা কমপক্ষে কিছু পরিসংখ্যান বোঝার জন্য এমন সরঞ্জামের প্রয়োজন হবে সর্বাধিক সম্ভাব্য শব্দের সংকলনের সাথে কী শব্দগুলি একসাথে পাওয়া যাবে সে সম্পর্কিত তথ্য। দেখে মনে হচ্ছে সমাধানটি একটি বিশেষায়িত লাইব্রেরি যা লিন খুঁজে পেয়েছে


@terdon, সম্পাদনা দেখুন। সমস্যাটি হ'ল এই প্রশ্নটি একটি জটিল এবং আকর্ষণীয় থেকে তুচ্ছ হিসাবে পরিবর্তিত হয়েছিল। সম্পাদনার আগে এবং পরে যে দুটি প্রশ্নের মধ্যে আপনি এটি দুটি প্রশ্নে বিভক্ত করতে পারেন সে উপায় কি?
স্টাফেন চেজেলাস

আমি ভীত, না। নিখুঁত না হলেও এখনও একটি চালাক কৌশল।
টেরডন

1
কঠোরভাবে বলতে গেলে, প্রশ্নটি প্রথম থেকেই তুচ্ছ ছিল - প্রথম সংস্করণ এবং এর উত্স দেখুন । দুর্ভাগ্যবশত, অপ বুঝতে পারে না কিভাবে স্ট্যাক এক্সচেঞ্জ টেক্সট উপস্থাপনা, তাই সঠিক ইনপুট টেক্সট দৃশ্যমান পর্যন্ত ছিল না trichoplax সংশোধন বিন্যাস - এবং আরও দুর্ভাগ্যবশত, এটা দৃশ্যমান ছিল না তারপর , কারণ যে ব্যক্তি যে সম্পাদন করা অবিলম্বে অনুমোদন গিয়ে তা ভেঙে ফেলল
স্কট

2

দেউই মরগানের সংস্করণটির মতো, তবে সেড সহ:

$ echo "f o o  t h e  b a r" | sed -r "s/[ ]{1}([^ ]{1})/\1/g"
foo the bar

এটি কেবল জিএনইউ sedএবং এটি দেবির সমতুল্য নয়। sedsed 's/ \( *\)/\1/g'
দেউবির

"অনুরূপ" নোট করুন ;-)
জ্যালিক্স

1

যদিও এটি পার্ল ওয়ান-লাইনারের সাহায্যে করা যেতে পারে (এবং হওয়া উচিত), একটি ছোট সি পার্সার খুব দ্রুত হবে এবং এটি খুব ছোটও (এবং আশাকরিও খুব সঠিক):

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char c1 = '\0', c2 = '\0', tmp_c;

  c1 = fgetc(stdin);
  for (;;) {
    if (c1 == EOF) {
      break;
    }
    c2 = fgetc(stdin);
    if (c2 == EOF) {
      if (c1 != ' ') {
        fputc(c1, stdout);
      }
      break;
    }
    if (c1 == c2 && c1 == ' ') {
      tmp_c = fgetc(stdin);
      if (tmp_c != EOF) {
        if (tmp_c != '\n') {
          ungetc(tmp_c, stdin);
          fputc(' ', stdout);
        } else {
          ungetc(tmp_c, stdin);
        }
      } else {
        break;
      }
    } else if (c1 != ' ') {
      fputc(c1, stdout);
    }
    c1 = c2;
  }
  exit(EXIT_SUCCESS);
}

সংকলিত

gcc-4.9 -O3 -g3  -W -Wall -Wextra -std=c11 lilcparser.c -o lilcparser

(প্রোগ্রামাম 9kb এর চেয়ে কিছুটা কম)

একটি পাইপে যেমন ব্যবহার করুন:

echo "T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t  " | ./lilcparser

1

আমি এটি চেষ্টা করেছিলাম এবং এটি কাজ করে বলে মনে হচ্ছে:

echo "<text here>" | sed -r 's/(\w)(\s)/\1/g'

sedকমান্ড দুই দলের এবং আয় শুধুমাত্র প্রথম ধারন করে না।


0

সি ++ এ, আমি এটি করব:

#include <fstream>
using namespace std;

int main()
{   
    fstream is("test.txt", std::ios::in);

    char buff;
    vector<char>str;

    while (!is.eof()){is.get(buff);str.push_back(buff);} //read file to string

    for (int a=0;a<str.size();++a)if (str[a] == ' ' && str[a + 1] != ' ')str.erase(str.begin()+a);
    is.close();

    ofstream os("test.txt", std::ios::out | std::ios::trunc); //clear file for rewrite

    os.write(str.data(), str.size() * sizeof(char)); //write chars
    os.close();

    return 0;
    }

পরীক্ষার পাঠ্য ফাইলের বিষয়বস্তুগুলিকে একই স্ট্রিংয়ে পরিবর্তিত করা হবে তবে অক্ষরের মধ্যবর্তী ফাঁকা স্থান সরিয়ে দেওয়া হবে। (প্রতিটি অক্ষরের মধ্যে নির্ভুল হওয়ার জন্য এটির জন্য একটি স্থান প্রয়োজন)।


0
$ echo 'F o u r  s c o r e  a n d' | \
txr -t '(mapcar* (opip (split-str @1 "  ")
                       (mapcar (op regsub #/ / ""))
                       (cat-str @1 " "))
                 (get-lines))'
Four score and


$ txr -e '(awk (:begin (set fs "  "))
               ((mf (regsub #/ / ""))))'  # mf: modify fields
F o u r  s c o r e  a n d
Four score and


$ awk -F'  ' '{for(i=1;i<=NF;i++)gsub(/ /,"",$i);print}'
F o u r  s c o r e  a n d
Four score and
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.