কমান্ড লাইন সরঞ্জামটি "বিড়াল" থেকে ফাইলের সমস্ত সারি জোড়া জোড় করে প্রসারিত


13

ধরুন আমার কাছে এমন একটি ফাইল রয়েছে (এটি নমুনা ডেস্কটেক্স কল করুন) যা দেখতে দেখতে এটি দেখতে:

Row1,10
Row2,20
Row3,30
Row4,40

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

Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row1,20 Row2,20
...
Row4,40 Row4,40

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

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

awk '{arr[$1]=$1} END{for (a in arr){ for (a2 in arr) { print arr[a] " " arr[a2]}}}' samples/rows.txt 
Row3,30 Row3,30
Row3,30 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row1,10 Row1,10
Row1,10 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20

মূলত মেমরিতে ফাইলটি স্টোর না করে এবং এন্ড ব্লকে আউটপুট না রেখে এটি করার কোনও দক্ষ স্ট্রিমিং উপায় কী?


1
অন্য ফাইলের দ্বিতীয় লাইনের জন্য আউটপুট উত্পাদন শুরু করার আগে আপনাকে সর্বদা একটি ফাইল পড়তে হবে। অন্য ফাইলটি আপনি স্ট্রিম করতে পারেন।
পুনরায় পোস্টার

উত্তর:


12

এটি কীভাবে বিশ্রীভাবে করা যায় তা যাতে এটি সম্পূর্ণ ফাইলটিকে অ্যারেতে সঞ্চয় করতে না পারে। এটি মূলত টেরডনের মতো একই অ্যালগরিদম।

আপনি যদি চান তবে আপনি এটি কমান্ড লাইনে একাধিক ফাইলের নামও দিতে পারেন এবং এটি প্রতিটি ফাইল স্বাধীনভাবে প্রক্রিয়া করবে, ফলাফলগুলি একসাথে যুক্ত করে ating

#!/usr/bin/awk -f

#Cartesian product of records

{
    file = FILENAME
    while ((getline line <file) > 0)
        print $0, line
    close(file)
}

আমার সিস্টেমে, এটি টেরডনের পার্ল সমাধানের প্রায় 2/3 সময়ের মধ্যে চলে।


1
ধন্যবাদ! এই সমস্যার সমস্ত সমাধান চমত্কার ছিল তবে আমি 1) সরলতা এবং 2) অবাস্তবলে থাকার কারণে এইটির সাথে শেষ করেছি। ধন্যবাদ!
টম হেডেন

1
টম, আপনি পছন্দ করেছেন। আমি আজকাল পাইথনগুলিতে বেশিরভাগ প্রোগ্রাম করার প্রবণতা রাখি তবে লাইন এবং ফাইলগুলির অন্তর্নির্মিত লুপগুলির কারণে আমি লাইন টেক্সট প্রসেসিংয়ের জন্য লাইন পছন্দ করি। এবং এটি প্রায়শই পাইথনের চেয়ে দ্রুত।
পিএম 2 রিং

7

আমি নই নিশ্চিত এই মেমরি এরকম বেশী ভালো, কিন্তু একটি সঙ্গে sedযে rতার infile মধ্যে যে লাইন এবং অন্য একটি পাইপ ওপারে তার এর infile আউট EADS পর্যায়ক্রমে Hইনপুট লাইনের পুরাতন স্থান ...

cat <<\IN >/tmp/tmp
Row1,10
Row2,20
Row3,30
Row4,40
IN

</tmp/tmp sed -e 'i\
' -e 'r /tmp/tmp' | 
sed -n '/./!n;h;N;/\n$/D;G;s/\n/ /;P;D'

আউটপুট

Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row3,30 Row3,30
Row3,30 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40

আমি এটি অন্যভাবে করেছি। এটি স্মৃতিতে কিছু সঞ্চয় করে - এটি স্ট্রিংয়ের মতো সঞ্চয় করে:

"$1" -

... ফাইলের প্রতিটি লাইনের জন্য।

pairs(){ [ -e "$1" ] || return
    set -- "$1" "$(IFS=0 n=
        case "${0%sh*}" in (ya|*s) n=-1;; (mk|po) n=+1;;esac
        printf '"$1" - %s' $(printf "%.$(($(wc -l <"$1")$n))d" 0))"
    eval "cat -- $2 </dev/null | paste -d ' \n' -- $2"
}

এটা খুব দ্রুত। এটি catফাইলটির যতবার আছে ততবার ফাইলটিতে লাইন রয়েছে a |pipe। পাইপের ওপারে যে ইনপুটটি ফাইলের মধ্যে লাইন থাকে ততবার ফাইলের সাথে একত্রীকরণ করা হয়।

case- স্টাফ শুধুমাত্র বহনযোগ্যতা জন্য yashএবং zshযখন বিভক্ত উভয় অ্যাড এক উপাদান mkshএবং poshউভয় এক হারান। ksh, dash, busybox, এবং bashসেখানে শূণ্যসমূহ যেমন দ্বারা মুদ্রিত হয় বহু ক্ষেত্রে যেমন ঠিক কাছে সব বিভক্ত printf। উপরে লিখিত হিসাবে আমার মেশিনে উল্লিখিত শেলগুলির প্রত্যেকের জন্য একই ফলাফল রেন্ডার করে।

তাহলে ফাইল খুব দীর্ঘ, হতে পারে $ARGMAXঅনেক বেশি তর্ক যে ক্ষেত্রে আপনাকে পরিচয় করিয়ে দিতে হবে সমস্যা xargsবা অনুরূপ হিসাবে ভাল।

আউটপুট অভিন্ন হওয়ার আগে আমি একই ইনপুট ব্যবহার করেছি। তবে, আমি যদি আরও বড় হয়ে যাই ...

seq 10 10 10000 | nl -s, >/tmp/tmp

এটি আমার আগে ব্যবহৃত (সানস 'সারি') এর মতো প্রায় একই রকম একটি ফাইল তৈরি করে - তবে 1000 লাইনে। আপনি নিজেই দেখতে পান এটি কত দ্রুত:

time pairs /tmp/tmp |wc -l

1000000
pairs /tmp/tmp  0.20s user 0.07s system 110% cpu 0.239 total
wc -l  0.05s user 0.03s system 32% cpu 0.238 total

1000 লাইনে শাঁসের মধ্যে পারফরম্যান্সে কিছুটা প্রকারভেদ রয়েছে - bashএটি খুব ধীরে ধীরে - তবে তারা যেভাবেই করেন কেবল কাজটিই আর্গ স্ট্রিং তৈরি করে (এর 1000 কপি filename -) প্রভাব ন্যূনতম। পারফরম্যান্সের মধ্যে পার্থক্য zsh- উপরে হিসাবে - এবং bashএখানে একটি সেকেন্ডের 100 তম।

এখানে অন্য সংস্করণ যা কোনও দৈর্ঘ্যের একটি ফাইলের জন্য কাজ করা উচিত:

pairs2()( [ -e "$1" ] || exit
    rpt() until [ "$((n+=1))" -gt "$1" ]
          do printf %s\\n "$2"
          done
    [ -n "${1##*/*}" ] || cd -P -- "${1%/*}" || exit
    : & set -- "$1" "/tmp/pairs$!.ln" "$(wc -l <"$1")"
    ln -s "$PWD/${1##*/}" "$2" || exit
    n=0 rpt "$3" "$2" | xargs cat | { exec 3<&0
    n=0 rpt "$3" p | sed -nf - "$2" | paste - /dev/fd/3
    }; rm "$2"
)

এটি /tmpএকটি আধা-এলোমেলো নামের সাথে এটির প্রথম যুক্তিতে একটি নরম লিঙ্ক তৈরি করে যাতে এটি অদ্ভুত ফাইলের নামগুলিতে ঝুলতে না পারে। এটি গুরুত্বপূর্ণ কারণ catএর পাইপগুলির মাধ্যমে পাইগুলিতে আরগগুলি দেওয়া হয় xargscatএর আউটপুট সংরক্ষণ করা হবে <&3যখন sed pঅনেক বার হিসাবে প্রথম ARG প্রতিটি লাইন rints সেখানে যে ফাইলে লাইন আছে - এবং এর স্ক্রিপ্ট একটি নল মাধ্যমে এটি খাওয়ানো হয়। আবার এর pasteইনপুটটিকে মার্জ করে, তবে এবার -এটির স্ট্যান্ডার্ড ইনপুট এবং লিঙ্কটির নামের জন্য আবার মাত্র দুটি যুক্তি লাগে /dev/fd/3

এটি শেষ - /dev/fd/[num]লিঙ্কটি - কোনও লিনাক্স সিস্টেমে এবং আরও অনেক কিছুতে কাজ করা উচিত, তবে যদি এটি একটি নামযুক্ত পাইপটি তৈরি করে না mkfifoএবং পরিবর্তে এটি ব্যবহার করা উচিত।

এটি শেষ কাজটি rmপ্রস্থান করার আগে তৈরি নরম লিঙ্ক।

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

time pairs2 /tmp/tmp | wc -l

1000000
pairs2 /tmp/tmp  0.30s user 0.09s system 178% cpu 0.218 total
wc -l  0.03s user 0.02s system 26% cpu 0.218 total

জোড়গুলি ফাংশনটি কোনও ফাইলের মধ্যে রয়েছে বলে মনে হয়, তা না হলে আপনি কীভাবে এটি ঘোষণা করবেন?

@ জিডার - আমি কীভাবে ঘোষণা করব? আপনি কেবল এটি টার্মিনালে অনুলিপি করতে পারেন?
মাইকসার্ভ

1
ফাংশনটি ঘোষণা করুন। আপনি তাই করতে পারেন! আমি ভেবেছিলাম আপনি নিউলাইনগুলি থেকে বাঁচতে পারবেন, আমি কেবল পাস্টিং কোড থেকে সতর্ক থাকি, যদিও ধন্যবাদ :) তবে এটি অত্যন্ত দ্রুত, দুর্দান্ত উত্তর!

@ জিদার - আমি সাধারণত লাইভ শেল এ লিখি ctrl+v; ctrl+jআমার মতো নতুন লাইন পেতে।
মাইকজার্ভ

@ জিডার - আপনাকে অনেক ধন্যবাদ এবং সতর্ক হওয়া বুদ্ধিমানের কাজ - আপনার পক্ষে ভাল। তারা কোনও ফাইলে পাশাপাশি কাজ করবে - আপনি এটিকে এবং . ./file; fn_nameসেই ক্ষেত্রে অনুলিপি করতে পারেন ।
মাইকসার্ভ

5

ঠিক আছে, আপনি সর্বদা এটি আপনার শেলের মধ্যে করতে পারেন:

while read i; do 
    while read k; do echo "$i $k"; done < sample.txt 
done < sample.txt 

এটি একটি ভাল চুক্তি আপনার তুলনায় ধীর হয় awkসমাধান (আমার মেশিনে, এটা ~ 11 সেকেন্ড 1000 লাইনের জন্য 0.3 সেকেন্ডের মধ্যে নিল ~ বনাম awk) কিন্তু অন্তত এটা কখনো মেমরি লাইনের দুয়েকের বেশি ঝুলিতে।

উপরের লুপটি আপনার উদাহরণটিতে থাকা খুব সাধারণ ডেটার জন্য কাজ করে। এটি ব্যাকস্ল্যাশগুলিতে শ্বাসরোধ করবে এবং এটি পিছনে এবং শীর্ষস্থানগুলি খাবে। একই জিনিসটির আরও শক্তিশালী সংস্করণ হ'ল:

while IFS= read -r i; do 
    while IFS= read -r k; do printf "%s %s\n" "$i" "$k"; done < sample.txt 
done < sample.txt 

perlপরিবর্তে আরেকটি পছন্দ ব্যবহার করা হয়:

perl -lne '$line1=$_; open(A,"sample.txt"); 
           while($line2=<A>){printf "$line1 $line2"} close(A)' sample.txt

উপরের স্ক্রিপ্টটি ইনপুট ফাইলের প্রতিটি লাইন ( -ln) পড়বে , এটি সংরক্ষণ করুন $l, sample.txtআবার খোলার জন্য এবং প্রতিটি লাইন প্রিন্ট করে $l। ফলাফলটি সমস্ত জোড়াযুক্ত সংমিশ্রণ হয় যখন কেবল 2 টি লাইন মেমরিতে কখনও সঞ্চিত থাকে। আমার সিস্টেমে, 0.6এটি 1000 লাইনে প্রায় সেকেন্ড সময় নিয়েছে ।


ওহ ধন্যবাদ! আমি আশ্চর্য হয়েছি কেন পার্ল
টম হেডেন

@ টমহেইডেন মূলত কারণ পার্ক, অ্যাজকের মতো, বাশের চেয়ে অনেক দ্রুত।
terdon

1
আপনার লুপটি ডাউন ডাউন করতে হয়েছিল। সেখানে 4 বিভিন্ন খারাপ অভ্যাস। তুমি ভালো জানো.
স্টাফেন চেজেলাস

1
@ স্টাফেনচেজেলাস ভাল, আপনার উত্তরটির ভিত্তিতে, এখানে কোনও echoসমস্যা হতে পারে এমন কোনও পরিস্থিতি আমি ভাবতে পারি নি । আমি যা লিখেছি (এখনই যোগ করেছি printf) তাদের সবার সাথে ঠিক কাজ করা উচিত? whileলুপ হিসাবে , কেন? এর সাথে কী হয়েছে while read f; do ..; done < file? অবশ্যই আপনি একটি forলুপ প্রস্তাব দিচ্ছেন না ! অন্য বিকল্প কি?
টেরডন

2
@ কুওগলম, যে কেউ এড়ানো উচিত তার একটি সম্ভাব্য কারণেই কেবল ইঙ্গিত দেয়। বাইরে ধারণাগত , নির্ভরযোগ্যতা , স্পষ্টতা , কর্মক্ষমতা এবং নিরাপত্তা দিক, যে শুধুমাত্র জুড়ে নির্ভরযোগ্যতা
স্টাফেন চেজেলাস

4

সহ zsh:

a=(
Row1,10
Row2,20
Row3,30
Row4,40
)
printf '%s\n' $^a' '$^a

$^aএকটি অ্যারেতে অ্যারের জন্য ব্রেস-জাতীয় সম্প্রসারণ (যেমন পছন্দ করা {elt1,elt2}) চালু হয়।


4

আপনি বেশ দ্রুত ফলাফলের জন্য এই কোডটি সংকলন করতে পারেন ।
এটি 1000 লাইনের ফাইলে প্রায় 0.19 - 0.27 সেকেন্ডে সম্পূর্ণ হয়।

এটি বর্তমানে 10000মেমরিতে রেখাগুলি পড়ছে (স্ক্রিনে মুদ্রণের গতি বাড়ানোর জন্য) যা যদি আপনার 1000প্রতি লাইনে অক্ষর থাকে তবে 10mbমেমরির চেয়ে কম ব্যবহার করবেন যা আমি মনে করি না যে সমস্যা হবে। আপনি যদিও এই বিভাগটি পুরোপুরি সরিয়ে ফেলতে পারেন এবং কেবল যদি স্ক্রিনে প্রিন্ট করে তবে এটি যদি কোনও সমস্যার কারণ হয়ে থাকে।

আপনি ফাইলটি সংরক্ষণ করতে ফাইলের নাম g++ -o "NAME" "NAME.cpp"
কোথায় NAMEতা ব্যবহার করে সংকলন করতে পারেন এবং এই কোডটিতে ফাইলটি সংরক্ষণ করা হয় NAME.cppfile

CTEST.cpp:

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <sstream>
int main(int argc,char *argv[])
{

        if(argc != 2)
        {
                printf("You must provide at least one argument\n"); // Make                                                                                                                      sure only one arg
                exit(0);
   }
std::ifstream file(argv[1]),file2(argv[1]);
std::string line,line2;
std::stringstream ss;
int x=0;

while (file.good()){
    file2.clear();
    file2.seekg (0, file2.beg);
    getline(file, line);
    if(file.good()){
        while ( file2.good() ){
            getline(file2, line2);
            if(file2.good())
            ss << line <<" "<<line2 << "\n";
            x++;
            if(x==10000){
                    std::cout << ss.rdbuf();
                    ss.clear();
                    ss.str(std::string());
            }
    }
    }
}
std::cout << ss.rdbuf();
ss.clear();
ss.str(std::string());
}

প্রদর্শন

$ g++ -o "Stream.exe" "CTEST.cpp"
$ seq 10 10 10000 | nl -s, > testfile
$ time ./Stream.exe testfile | wc -l
1000000

real    0m0.243s
user    0m0.210s
sys     0m0.033s

3
join -j 2 file.txt file.txt | cut -c 2-
  • অ-বিদ্যমান ক্ষেত্রের সাথে যোগ দিন এবং প্রথম স্থানটি সরিয়ে দিন

ফিল্ড 2 খালি এবং file.txt- তে থাকা সমস্ত উপাদানগুলির জন্য সমান তাই joinএটি প্রতিটি উপাদানকে অন্য সকলের সাথে একত্রিত করবে: এটি আসলে কার্টেসিয়ান পণ্য গণনা করছে।


2

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

import mmap
import re
with open('test.file', 'rt') as f1, open('test.file') as f2:
    with mmap.mmap(f1.fileno(), 0, flags=mmap.MAP_SHARED, access=mmap.ACCESS_READ) as m1,\
        mmap.mmap(f2.fileno(), 0, flags=mmap.MAP_SHARED, access=mmap.ACCESS_READ) as m2:
        for line1 in re.finditer(b'.*?\n', m1):
            for line2 in re.finditer(b'.*?\n', m2):
                print('{} {}'.format(line1.group().decode().rstrip(),
                    line2.group().decode().rstrip()))
            m2.seek(0)

পাইথনে পর্যায়ক্রমে একটি দ্রুত সমাধান, যদিও মেমরির দক্ষতা এখনও উদ্বেগের কারণ হতে পারে

from itertools import product
with open('test.file') as f:
    for a, b  in product(f, repeat=2):
        print('{} {}'.format(a.rstrip(), b.rstrip()))
Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row3,30 Row3,30
Row3,30 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40

এটি কি সংজ্ঞা অনুসারে পুরো ফাইলটিকে স্মৃতিতে রাখবে না? আমি পাইথন জানি না তবে আপনার ভাষা অবশ্যই পরামর্শ দেয়।
টেরডন

1
@ ইটারডন, আপনি যদি মেমরি-ম্যাপিং সমাধানটি উল্লেখ করছেন তবে ওএস স্বচ্ছভাবে কেবলমাত্র ফাইলের পরিমাণ মেমরিতে রাখবে যা উপলব্ধ শারীরিক র‌্যামের উপর নির্ভর করে afford উপলব্ধ শারীরিক র‍্যাম ফাইলের আকার অতিক্রম করতে হবে না (যদিও অতিরিক্ত শারীরিক র‌্যাম থাকা অবশ্যই একটি সুবিধাজনক পরিস্থিতি হতে পারে)। সবচেয়ে খারাপ ক্ষেত্রে এটি ডিস্কে ফাইলের মাধ্যমে লুপিংয়ের গতিতে খারাপ হতে পারে বা আরও খারাপ হতে পারে। এই পদ্ধতির সঙ্গে কী সুবিধা পাওয়া যায় প্রকৃত RAM স্বচ্ছ ব্যবহার প্রভৃতির মতো এই কিছু সময়ের ওঠানামা পারে হয়
Iruvar

1

ব্যাশে, ksh পাশাপাশি কাজ করা উচিত, কেবল শেল্ট বিল্ট-ইনগুলি ব্যবহার করে:

#!/bin/bash
# we require array support
d=( $(< sample.txt) )
# quote arguments and
# build up brace expansion string
d=$(printf -- '%q,' "${d[@]}")
d=$(printf -- '%s' "{${d%,}}' '{${d%,}}")
eval printf -- '%s\\n' "$d"

মনে রাখবেন যে এটি শেল ভেরিয়েবলের মধ্যে মেমরির পুরো ফাইলটি ধারণ করে, এটিতে কেবল এটিতে একটি একক পঠনের অ্যাক্সেস প্রয়োজন।


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

হ্যাঁ, এটি ঠিক সঠিক - আমার কাছে এমন একটি বিশাল সংখ্যক ডেটা ফাইল রয়েছে যা আমার এটি করা দরকার এবং মেমরি ধরে রাখতে চাই না
টম হেডেন

যদি আপনি যে মেমরি দ্বারা constrainted, আমি @terdon সমাধান সমষ্টির ব্যবহার সুপারিশ করবে হয়
Franki

0

sed সমাধান।

line_num=$(wc -l < input.txt)
sed 'r input.txt' input.txt | sed -re "1~$((line_num + 1)){h;d}" -e 'G;s/(.*)\n(.*)/\2 \1/'

ব্যাখ্যা:

  • sed 'r file2' file1 - ফাইল 1 এর প্রতিটি লাইনের জন্য ফাইল 2 এর সমস্ত ফাইল সামগ্রী পড়ুন।
  • নির্মাণ 1~i1-ম লাইন, তারপর 1 + I লাইন, 1 + + 2 * আমি, 1 +3 * আমি, ইত্যাদি অতএব, যার মানে 1~$((line_num + 1)){h;d}মানে hবাফার পুরানো সরু লাইন, delete প্যাটার্ন স্থান এবং নতুন চক্র শুরু।
  • 'G;s/(.*)\n(.*)/\2 \1/'- পূর্ববর্তী ধাপে বাছাই করা ব্যতীত সমস্ত রেখার জন্য, পরবর্তী কাজটি করুন: Gহোল্ড বাফার থেকে এটি লাইন এবং এটি বর্তমান লাইনে সংযুক্ত করুন। তারপরে লাইনের জায়গাগুলি অদলবদল করুন। ছিল current_line\nbuffer_line\n, হয়ে গেছেbuffer_line\ncurrent_line\n

আউটপুট

Row1,10 Row1,10
Row1,10 Row2,20
Row1,10 Row3,30
Row1,10 Row4,40
Row2,20 Row1,10
Row2,20 Row2,20
Row2,20 Row3,30
Row2,20 Row4,40
Row3,30 Row1,10
Row3,30 Row2,20
Row3,30 Row3,30
Row3,30 Row4,40
Row4,40 Row1,10
Row4,40 Row2,20
Row4,40 Row3,30
Row4,40 Row4,40
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.