নির্দিষ্ট সংখ্যক শব্দের সাথে পাঠ্য ফাইলকে লাইনে বিভক্ত করুন


11

সম্পর্কিত, তবে কোনও সন্তোষজনক উত্তর নেই: আমি কীভাবে একটি বৃহত পাঠ্য ফাইলটি 500 শব্দের বাছুর মধ্যে ভাগ করতে পারি?

আমি > 10 ^ 7 শব্দের সাথে একটি লাইনে একটি পাঠ্য ফাইল ( http://mattmahoney.net/dc/text8.zip ) নেওয়ার চেষ্টা করছি এবং প্রতিটি এন শব্দ দিয়ে রেখায় বিভক্ত করছি। আমার বর্তমান পদ্ধতির কাজ করে তবে এটি বেশ ধীর এবং কুরুচিপূর্ণ (শেল স্ক্রিপ্ট ব্যবহার করে):

i=0
for word in $(sed -e 's/\s\+/\n/g' input.txt)
do
    echo -n "${word} " > output.txt
    let "i=i+1"

    if [ "$i" -eq "1000" ]
    then
        echo > output.txt
        let "i=0"
    fi
done

আমি কীভাবে এটি আরও দ্রুত বা আরও কমপ্যাক্ট করতে পারি তার কোনও পরামর্শ?


আপনি যদি এটি দ্রুত চান, আপনাকে অন্য কিছু ব্যবহার করতে হবে তবে বশ স্ক্রিপ্ট। আমি কিছু সি সুপারিশ করব এটি কয়েকটি লাইনে ফিট করতে পারে।
জাকুজে

উত্তর:


5

আপনার শব্দের সংজ্ঞাটি ধরে নেওয়া হ'ল ফাঁকা অক্ষর দ্বারা ফাঁকা আলাদা অক্ষরগুলির ক্রম, এটি awkআপনার একক-লাইন ফাইলের জন্য একটি সমাধান

awk '{for (i=1; i<=NF; ++i)printf "%s%s", $i, i % 500? " ": "\n"}i % 500{print ""}' file

11

ব্যবহার xargs(17 সেকেন্ড):

xargs -n1000 <file >output

এটি সর্বোচ্চ ব্যবহার করে যুক্তিগুলির সংখ্যার সংজ্ঞা দেয় এমন -nপতাকা ব্যবহার করে xargs। শুধু পরিবর্তন 1000করতে 500বা যাই হোক না কেন সীমাবদ্ধ আপনি চান।

আমি 10 ^ 7 শব্দ দিয়ে একটি পরীক্ষা ফাইল তৈরি করেছি:

$ wc -w file
10000000 file

সময় পরিসংখ্যান এখানে:

$ time xargs -n1000 <file >output
real    0m16.677s
user    0m1.084s
sys     0m0.744s

আমি যে উত্তরটি গ্রহণ করেছি তার তুলনায় এটি কিছুটা ধীর গতির (আমার ফাইলে 21 স বনাম 12

1
দুর্দান্ত ধারণা +1, তবে xargsএর উদ্ধৃতি-
প্রত্যাহার

এটি যত কম nধীরে ধীরে পাবে, ঠিক তেমনই আপনি জানেন। সঙ্গে -n10আমি অপেক্ষা 8 মিনিট পর এটিকে বাতিল করা হয়েছে ...
don_crissti

7

পার্ল এতে আশ্চর্যজনকভাবে ভাল বলে মনে হচ্ছে:

10,000,000 স্পেস বিচ্ছিন্ন শব্দের সাথে একটি ফাইল তৈরি করুন

for ((i=1; i<=10000000; i++)); do printf "%s " $RANDOM ; done > one.line

এখন, প্রতি 1000 শব্দের পরে একটি নতুন লাইন যুক্ত করতে পার্ল করুন

time perl -pe '
    s{ 
        (?:\S+\s+){999} \S+   # 1000 words
        \K                    # then reset start of match
        \s+                   # and the next bit of whitespace
    }
    {\n}gx                    # replace whitespace with newline
' one.line > many.line

টাইমিং

real    0m1.074s
user    0m0.996s
sys     0m0.076s

ফলাফল যাচাই করুন

$ wc one.line many.line
        0  10000000  56608931 one.line
    10000  10000000  56608931 many.line
    10000  20000000 113217862 total

স্বীকৃত অজানা সমাধানটি আমার ইনপুট ফাইলে মাত্র 5 সেকেন্ডের মধ্যে নিয়েছে।


5

Nশব্দের ওম্বার বড় সংখ্যা হলে সত্যই উপযুক্ত নয় তবে এটি যদি অল্প সংখ্যক হয় (এবং আদর্শভাবে, আপনার এক-লাইন ফাইলে কোনও নেতৃস্থানীয় / পিছনে স্থান নেই) এটি বেশ দ্রুত হওয়া উচিত (উদাহরণস্বরূপ প্রতি লাইনে 5 শব্দ):

tr -s '[[:blank:]]' '\n' <input.txt | paste -d' ' - - - - - >output.txt

1
এটি বৃহত সংখ্যার সাথে পুরোপুরি ঠিক আছে, এবং অন্ধভাবে দ্রুত। কেবল pasteউড়তে স্ট্রিং তৈরি করুন । উদাহরণস্বরূপ:tr -s '[[:blank:]]' '\n' < text8 | paste -d' ' $(perl -le 'print "- " x 1000')
টেরডন

@ ইটারডন - সত্য, যদিও প্রচুর সংখ্যক লোকের জন্য কমান্ড আর্গুমেন্টগুলি তৈরি করতে হবে যেমন আপনি যেমন করেছিলেন বা setইত্যাদি দ্বারা ... এবং তারপরেও একটি যুক্তি রয়েছে সুনির্দিষ্ট সর্বোচ্চ সংখ্যক যুক্তি (আমি এর সমস্ত স্বাদের সাথে পরিচিত নই pasteতবে) আমি মনে করি কিছু বাস্তবায়নের সাথে আরগস / ইনপুট ফাইল এবং / অথবা আউটপুট লাইনের দৈর্ঘ্যের
সীমাবদ্ধতা রয়েছে

3

আপনি কত শব্দের স্পেস নিদর্শন মেলে চান তা উল্লেখ করে একই সেড কমান্ডটি সরল করা যায়। এটি পরীক্ষা করার জন্য আমার কাছে বড় স্ট্রিং ফাইল নেই, তবে আপনার মূল স্ক্রিপ্টের লুপগুলি ছাড়া এটি আপনার প্রসেসরের ডেটা প্রবাহিত করতে পারে তত দ্রুত চালানো উচিত। যোগ করা সুবিধা, এটি মাল্টি-লাইন ফাইলগুলিতে সমানভাবে ভাল কাজ করবে।

n=500; sed -r "s/((\w+\s){$n})/\1\n/g" <input.txt >output.txt

3

সম্মানজনক fmt(1)কমান্ড, "নির্দিষ্ট সংখ্যক শব্দের উপর" কঠোরভাবে অপারেশন না করে, নির্দিষ্ট লক্ষ্যে (বা সর্বোচ্চ) প্রস্থের জন্য দীর্ঘ লাইনগুলি প্রায় দ্রুত আবদ্ধ করতে পারে:

perl -e 'for (1..100) { print "a"x int 3+rand(7), " " }' | fmt

বা আধুনিক পার্ল সহ, একটি নির্দিষ্ট সংখ্যক শব্দের জন্য, 10 বলুন, এবং একটি একক স্থান শব্দের সীমানা হিসাবে ধরে নেওয়া:

... | perl -ple 's/(.*? ){10}\K/\n/g'

2

কোর্টিলস prকমান্ডটি অন্য প্রার্থী: একমাত্র বলি মনে হয় যে পৃষ্ঠার প্রস্থটি আউটপুট প্রস্থকে সামঞ্জস্য করতে যথেষ্ট বড় হতে বাধ্য করা প্রয়োজন।

@ গ্লেন_ জ্যাকম্যানের 10,000,000 শব্দ জেনারেটর ব্যবহার করে তৈরি করা একটি ফাইল ব্যবহার করে,

$ time tr '[[:blank:]]' '\n' < one.line | pr -s' ' -W 1000000 -JaT -1000 > many.line

real    0m2.113s
user    0m2.086s
sys 0m0.411s

নীচে হিসাবে গণনা নিশ্চিত করা হয়েছে যেখানে

$ wc one.line multi.line 
        0  10000000  56608795 one.line
    10000  10000000  56608795 many.line
    10000  20000000 113217590 total

[গ্লেনের পার্ল দ্রবণটি এখনও কিছুটা দ্রুত, এই মেশিনে 1.8 ডলার]।


1

Go এ আমি এটির মতো চেষ্টা করব

//wordsplit.go

//$ go run wordsplit.go bigtext.txt

package main


import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "strings"
)


func main() {
    myfile, err := os.Open(os.Args[0])
    if err != nil {
        log.Fatal(err)
    }
    defer myfile.Close()
    data, err := ioutil.ReadAll()
    if err != nil {
        log.Fatal(err)
    }
    words := strings.Split(data, " ")
    newfile, err := os.Create("output.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer newfile.Close()
    for i := 0; i < len(words)-10; i+10 {
        newfile.WriteString(words[i:i+10])
    }
    newfile.WriteString(words[-(len(words)%10):])
    fmt.Printf("Formatted %s into 10 word lines in output.txt", os.Args[0])
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.