পাঠ্য ফাইল থেকে স্ট্রিং বিভক্ত করার দ্রুত পদ্ধতি?


11

আমার কাছে দুটি পাঠ্য ফাইল রয়েছে: স্ট্রিং.টেক্সট এবং দৈর্ঘ্য.টিএসটিএসটি

String.txt:

abcdefghijklmnopqrstuvwxyz

lengths.txt

5
4
10
7

আমি ফাইল পেতে চাই

>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

আমি প্রায় ২৮,০০০ এন্ট্রি নিয়ে কাজ করছি এবং এগুলি ২০০ থেকে ৫,000,০০০ বর্ণের মধ্যে পরিবর্তিত হয়।

এই মুহুর্তে, আমি ব্যবহার করছি:

start=1
end=0
i=0
while read read_l
do
    let i=i+1
    let end=end+read_l
    echo -e ">Entry_$i" >>outfile.txt
    echo "$(cut -c$start-$end String.txt)" >>outfile.txt
    let start=start+read_l
    echo $i
done <lengths.txt

তবে এটি খুব অদক্ষ। আরও ভাল ধারণা?


str="$(cat string.txt)"; i=0; while read j; do echo "${file:$i:$j}"; i=$((i+j)); done <length.txtকেবল শেল দ্বারা সম্পন্ন হিসাবে কীভাবে ..সম্পূর্ণ পর্যায়ে ..
হিমাইল

সৎ হওয়া খুব দ্রুত নয়। এটি এখনও বেশ দীর্ঘ সময় নিচ্ছে। আমি লিনাক্স / প্রোগ্রামিংয়ে বেশ নতুন তাই আপনি যদি মনে করেন কেবল শেল ব্যবহার না করে একটি দ্রুত পদ্ধতি আছে তবে আমি ধারণাগুলির জন্য উন্মুক্ত।
ব্যবহারকারী 3891532

4
ব্যবহার করে দেখুন { while read l<&3; do head -c"$l"; echo; done 3<lengths.txt; } <String.txt
জিম্মিজ

@ জিম্মিজ, কীভাবে উত্তরটি আটকে রাখবেন
ইরুবার

উত্তর:


7

আপনি করতে পারেন

{
  while read l<&3; do
    {
      head -c"$l"
      echo
    } 3<&-
  done 3<lengths.txt
} <String.txt

এর কিছু ব্যাখ্যা দরকার:

মূল ধারণাটি ব্যবহার করা { head ; } <fileএবং অবমূল্যায়িত @ মাইক্রোসভার উত্তর থেকে প্রাপ্ত । তবে এক্ষেত্রে আমাদের অনেকগুলি ব্যবহার করা দরকার head, সুতরাং whileলুপটি চালু করা হয়েছে এবং headউভয় ফাইল থেকে ইনপুট প্রবেশের জন্য ফাইল বর্ণনাকারীদের সাথে সামান্য কিছুটা টুইট করা হয়েছে ( String.txtপ্রক্রিয়াতে একটি প্রধান ফাইল হিসাবে ফাইল এবং বিকল্পের length.txtপক্ষে একটি আর্গুমেন্ট হিসাবে লাইন -c) । ধারণাটি হ'ল গতিতে সুবিধাগুলি String.txtপ্রতিবারের মতো আদেশ headবা অনুরোধ করার সময় প্রতিটি সময় নেওয়ার দরকার নেই cutechoপ্রতিটি পুনরাবৃত্তির পরে কেবল নিউলাইন মুদ্রণ করা।

এটি কত দ্রুত (যদি থাকে) এবং >Entry_iলাইনের মধ্যে যোগ করা অনুশীলন হিসাবে ছেড়ে যায়।


I / O পুনঃনির্দেশের ঝরঝরে ব্যবহার। যেহেতু ট্যাগটি লিনাক্স, আপনি যুক্তিযুক্তভাবে শেলটি বাশ এবং ধরে নিতে পারেন এবং read -u 3বিবরণী 3 থেকে পড়তে ব্যবহার করতে পারেন
জোনাথন লেফলার

@ জোনাথন লেফলার, লিনাক্স এর সাথে খুব একটা সম্পর্ক নেই bash। লিনাক্স-ভিত্তিক প্রচুর সিস্টেমে bashইনস্টলড নেই (Android এবং অন্যান্য এমবেডেড সিস্টেমগুলি ভাবেন)। bashসব ধীরতম শেল হচ্ছে ব্যাশ স্যুইচ হবে সম্ভবত জমিতে কর্মক্ষমতা আরো উল্লেখযোগ্যভাবে তুলনায় সামান্য লাভ থেকে সুইচিং read <&3করতে read -u3যথাসাধ্য আনা (যার কোনো ক্ষেত্রে তুচ্ছ মত একটি বহিস্থিত কমান্ড চলমান খরচ তুলনা করা হবে head)। Ksh93 এ স্যুইচ করা যা অন্তর্নির্মিত head(এবং এক যে মানহীন বিকল্পকে সমর্থন করে -c) আরও অনেক বেশি পারফরম্যান্সের উন্নতি করবে।
স্টাফেন চ্যাজেলাস

মনে রাখবেন যে head -c( headবাস্তবায়নের জন্য যেখানে সেই মানহীন বিকল্প উপলব্ধ রয়েছে) এর যুক্তি হ'ল অক্ষর নয় a এটি মাল্টি-বাইট লোকেলে একটি পার্থক্য তৈরি করবে।
স্টাফেন চেজেলাস

7

সাধারণত, আপনি পাঠ্য প্রক্রিয়া করতে শেল লুপ ব্যবহার করতে চান না । এখানে, আমি ব্যবহার করব perl:

$ perl -lpe 'read STDIN,$_,$_; print ">Entry_" . ++$n' lengths.txt < string.txt
>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

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

( -Cঅপশন যুক্ত করুন যদি এই সংখ্যাগুলি বাইটের সংখ্যার বিপরীতে বর্তমান লোকেলগুলিতে অক্ষরের সংখ্যা হওয়া উচিত sample যেমন আপনার নমুনায় যেমন ASCII অক্ষর রয়েছে তবে এতে কোনও তফাত হবে না)।


এটি $_উভয় আউটপুট এবং ইনপুট প্যারামিটার হিসাবে একটি পুনরুদ্ধার পুনরায় ব্যবহার read, কিন্তু এটি স্ক্রিপ্টে বাইট গণনা হ্রাস করে।
জোনাথন লেফলার

একটি দ্রুত পরীক্ষায় ( ওপি'র নমুনাটি 100000 বার পুনরাবৃত্তি হয়েছিল), আমি দেখতে পাচ্ছি যে এই সমাধানটি @ জিম্মিজের ( ০.০ সেকেন্ড বনাম minutes মিনিট (সহ bash, ১ seconds সেকেন্ড সহ PATH=/opt/ast/bin:$PATH ksh93)) প্রায় 1200 গুণ দ্রুত ।
স্টাফেন চেজেলাস

6

বাশ, সংস্করণ 4

mapfile -t lengths <lengths.txt
string=$(< String.txt)
i=0 
n=0
for len in "${lengths[@]}"; do
    echo ">Entry_$((++n))"
    echo "${string:i:len}"
    ((i+=len))
done

আউটপুট

>Entry_1
abcde
>Entry_2
fghi
>Entry_3
jklmnopqrs
>Entry_4
tuvwxyz

4

কি হবে awk?

process.awkএই কোড সহ কল ​​করা একটি ফাইল তৈরি করুন :

function idx(i1, v1, i2, v2)
{
     # numerical index comparison, ascending order
     return (i1 - i2)
}
FNR==NR { a[FNR]=$0; next }
{ i=1;PROCINFO["sorted_in"] = "idx";
        for (j in a) {
                print ">Entry"j;
                ms=substr($0, i,a[j])
                print ms
                i=i+length(ms)
        }
}

এটি সংরক্ষণ করুন এবং সম্পাদন করুন awk -f process.awk lengths.txt string.txt


ব্যবহারের ভিত্তিতে, এটি PROCINFOমানক নয় awk, তবে gawkgawkসেক্ষেত্রে আমি আর একমাত্র বৈশিষ্ট্যটি পছন্দ করব FIELDWIDTHS:awk -vFIELDWIDTHS="$(tr '\n' ' ' < lengths.txt)" '{for(i=1;i<=NF;i++)print">Entry"i ORS$i}' string.txt
ম্যানটওয়ার্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.