ডিলিমিটার ট্রিপল পাইপ প্রতীক "|||" এর সাহায্যে দুটি ফাইল লাইনে একত্র করুন


14

আমার কাছে দুটি ভাষায় একই সংখ্যার লাইনের সাথে দুটি সমান্তরাল ফাইল রয়েছে এবং এই দুটি ফাইলকে লাইন দিয়ে ডেলিফিমারের সাথে একীভূত করার পরিকল্পনা রয়েছে |||। উদাহরণস্বরূপ, দুটি ফাইল নিম্নরূপ:

ফাইল এ:

1Mo 1,1 I love you.
1Mo 1,2 I like you.
Hi 1,3 I am hungry.
Hi 1,4 I am foolish.

ফাইল বি:

1Mo 1,1 Ich liebe dich.
1Mo 1,2 Ich mag dich.
Hi 1,3 Ich habe Durst.
Hi 1,4 Ich bin neu.

প্রত্যাশিত আউটপুটটি এরকম:

1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.

আমি pasteকমান্ডটি চেষ্টা করেছিলাম যেমন:

paste -d "|||" fileA fileB

তবে ফিরে আসা আউটপুটে কেবল একটি পাইপ রয়েছে যেমন:

1Mo 1,1 I love you. |1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. |1Mo 1,2 Ich mag dich.

ট্রাইপ পাইপ দ্বারা প্রতিটি জোড়া লাইন আলাদা করার কোনও উপায় আছে কি |||?


8
paste -d '|||' fileA - - fileB < /dev/null
স্টাফেন চেজেলাস

5
অফটোপিক, তবে আপনার অনুবাদগুলি সঠিক নয়;) "Ich habe Durst" = I thisrty, "Ich bin neu" = আমি নতুন ... অগত্যা এর অর্থ এই নয় যে আপনি বোকা। ... কেবলমাত্র যদি আপনি প্রকৃতপক্ষে জার্মান ভাষা
শিখেন


পুনঃটুইট
ভ্রূণু

উত্তর:


20

সঙ্গে POSIX পেস্ট :

:|paste -d ' ||| ' fileA - - - - fileB

pasteসমস্ত ইনপুট ফাইল সম্পর্কিত লাইন একত্রিত করা হবে। এখানে আমাদের কাছে ছয়টি ফাইল, fileAস্ট্যান্ডার্ড থেকে চারটি ডামি ফাইল -এবং fileB

ডিলিমিটারগুলির তালিকার মধ্যে একটি স্থান, তিনটি পাইপ এবং সেই ক্রমের একটি স্থান pasteবিজ্ঞপ্তি দ্বারা ব্যবহৃত হবে ।

ছয় ফাইলের প্রথম লাইন জন্য, fileAপ্রথম ডামি ফাইল সঙ্গে ঘনিভূত হবে (যা কিছুই, ধন্যবাদ : কোন সমিতি , উত্পাদন অপারেটর) line1-fileA<space>

প্রথম ডামি ফাইলটি দ্বিতীয় দ্বারা একটি পাইপ দ্বারা উত্পাদিত হবে line1-fileA |, তারপরে তৃতীয় ডামি ফাইলের সাথে দ্বিতীয় ডামি ফাইল, উত্পাদন line1-fileA ||, তৃতীয় ডামি ফাইলটি সামনে ডামি ফাইলের সাথে উত্পাদন করবে line1-fileA |||

এবং সামনে ডামি ফাইল fileB, উত্পাদন line1-fileA ||| line1-fileB

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


এর ব্যবহার :|হ'ল কম-টাইপিংয়ের জন্য এবং মূলত ইন্টারেক্টিভ শেলটিতে ব্যবহৃত হয়। স্ক্রিপ্টে আপনার ব্যবহার করা উচিত:

</dev/null paste -d ' ||| ' fileA - - - - fileB

একটি সাবস্কেল তৈরি হওয়া থেকে আটকাতে।


1
জন্য +1 :|। চতুর বিকল্প</dev/null
ক্যাস

4
... এবং স্ট্যান্ডার্ড ইনপুট থেকে 4 টি ডামি ফাইলের স্মার্ট ব্যবহারের জন্য +1 - - - -, তবে পরের বার আপনি ব্যাখ্যাটির জন্য কয়েকটি লাইনও লিখতে পারেন :)
হাস্তুর

থেক্স, তবে আমি এখনও একটি পাইপ দিয়ে আউটপুট
পেয়েছি

@ হুই, আপনি কি সমস্ত ড্যাশ এবং স্পেস ক্যারেক্টার সহ ঠিক কমান্ডটি চালিয়েছেন? আপনার অপারেটিং সিস্টেমটি কী?
স্টাফেন চেজেলাস

:|paste -d '|' fileA - - fileBস্পেস ডিলিমিটার ছাড়াই আরও সঠিক সংস্করণ দেয়।
পোল জিডি

7

ঠিক আছে, এটি সেড, অবাক বা গ্রেপ ব্যবহার করে না তবে আপনি এটি খুব সহজেই ব্যাশে করতে পারেন। আদেশটি হ'ল:

(while IFS= read -r a <&3 && IFS= read -r b <&4; do echo "$a ||| $b"; done) 3<fileA 4<fileB

পেস্টের সমস্যাটি হ'ল ডিলিমিটারটি একক অক্ষর। এটি রূপান্তর করতে আপনি একটি একক অক্ষর এবং সেড ব্যবহার সন্নিবেশ করতে পারেন তবে অক্ষরটি ইনপুট ফাইলে উপস্থিত থাকলে এটি ত্রুটি-প্রবণতা জাতীয় হবে be


2
লাইনে কোনও ব্যাকস্ল্যাশ অক্ষর থাকে বা ড্যাশ দিয়ে শুরু করা হলে আপনার সমাধান কাজ করবে না। আপনি IFS=প্রতিটি আগে ব্যবহার করতে চান read। আপনি এটি দিয়ে সহজেই এটি করতে পারেন paste। দেখুন আমার উত্তর এছাড়াও, এবং এই এক দেখুন কেন ব্যবহার এড়িয়ে চলা উচিত whileশেল স্ক্রিপ্ট-এ লুপ।
cuonglm

এটি আমার ফাইলের জন্য কাজ করে। অনেক Thx !!!
ভ্রূণু

5

একটি awk (GNU) সংস্করণ

awk '{printf ("%s ||| ", $0); getline < "fileB"; print $0 }' fileA

সঙ্গে getlineকমান্ড awk, আপনি সেট করতে পারেন $0, পরবর্তী ইনপুট রেকর্ড থেকে (কলামের জন্য সব ভেরিয়েবল) যদি getline < "filename"আপনি পরবর্তী সেট $0নির্বাচিত ফাইল থেকে।

getline <"file" ফাইলের পরবর্তী রেকর্ড থেকে সেট $ 0; এনএফ সেট করুন।


আপনার প্রচেষ্টা যেমনটি আশা করেছিলেন তেমন কার্যকর হয়নি কেন? থেকে man pasteআমরা পড়তে পারি

-d, --delimiters=LIST
     reuse characters from LIST instead of TABs

তবে এটি প্রতিটি কলামের জন্য ডিলিমিটার ব্যবহার করে

কমান্ডটি
paste -d '|*|*' fileA fileB fileA fileBআমাকে যেমন লাইন দেয়

Hi 1,3 I am hungry.|Hi 1,3 Ich habe Durst.*Hi 1,3 I am hungry.|Hi 1,3 Ich...
Hi 1,4 I am foolish.|Hi 1,4 Ich bin neu.*Hi 1,4 I am foolish.|Hi 1,4 Ich...


এমন একটি sedসমাধান যা আমি আপনার মূল প্রচেষ্টার কাছাকাছি থাকলেও এড়াতে পরামর্শ দিই কারণ এটি প্রাপ্ত আচরণকে আপনার মূল উদ্দেশ্যকে প্যাচ করে:

 paste -d '|' fileA fileB | sed 's/|/|||/g'

কারণ আপনি প্রতিটি প্যাটার্ন প্রতিস্থাপন এড়ানোর জন্য |নতুন পাসওয়ার্ড দিয়ে |||, কিন্তু আপনি যে অনুমান করা নল প্রতীক (আছে |) কোনো ডাটা উপস্থিত না , অন্য আপনি বিশেষ ক্ষেত্রে সঙ্গে কারবার এড়ানোর পার্শ্ব প্রতিক্রিয়া করার জন্য একটি আরো জটিল কোড করা আছে।


এখানে স্ট্রিং [ 1 ] নির্মাণের সাথে একটি বৈকল্পিক<<<

 paste -d ' ||| ' fileA - - - - fileB  <<< ''

আপনি -d ' ||| '(স্থান, |, |, |, স্থান) এবং 4 টি ডামি ফাইল ( - - - -) দিয়ে 5 টি ডিলিমিটার সেট করেছেন যা খালি স্ট্রিং থেকে ডেটা নেবে ''


জিএনইউ অ্যাওক ৪.০.১-তে পরীক্ষা করা হয়েছে, পেস্ট (জিএনইউ কোর্টিল) ৮.২১ এবং সেড (জিএনইউ সেড) ৪.২.২


থেক্স, অ্যাড কমান্ড কাজ করে!
ভ্রমন

1
ইউআর স্বাগতম। sed(:-)) এবং আরও মন্তব্য এড়ানোর জন্য একটি উদাহরণ যুক্ত উত্তর আপডেট করেছে ।
হাস্তুর

4

আপনি যদি বিজ্ঞপ্তিযুক্ত ডিলিমিটার এবং ডামি ফাইলগুলির যাদু এবং নাটক এড়াতে চান, আপনি কেবল আপনার ডিলিমিটারকে একটি ফাইলের সাথে সংযুক্ত করার আগে এটিকে যুক্ত করতে পারেন:

paste <(sed 's/$/ |||/' filea) fileb

দেয়

1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. |||    Hi 1,4 Ich bin neu.

আমি সরলতার জন্য এটি পছন্দ করি। আমি বিশ্বাস করি আপনার অর্থ "প্রিপেন্ড", যদিও "সংযোজন" নয়। এর অজস্র সংস্করণটির জন্য চেকআউট হস্তুরের দুর্দান্ত উত্তর।
ওয়াইল্ডকার্ড

আপনার প্রক্রিয়াটির বিকল্পটি পাইপতে পরিবর্তন করা উচিত, যাতে শেল সংখ্যা সমর্থন করার জন্য আপনার সীমা থাকে না।
cuonglm

@ উইল্ডকার্ড হ্যাঁ, প্রিপেন্ড করুন, তবে ফাইলায় সংযুক্ত করার জন্য আমি এটি আবার লিখব rite আমি মনে করি এর জন্য বিশ্রীটি কিছুটা ওভারকিল।
সান্থে

@ কুওগলম সত্য, তবে আমি স্বচ্ছতার জন্য পাইপগুলি এড়াতে চেয়েছিলাম। আমি একটি নল এটা ডামি ফাইল মত চেহারা শুরু করতে হবে অনুভূত, কিন্তু আপনি সঠিক
snth

0

আপনি অজগর থেকেও এইভাবে করতে পারেন।

lines1 = [ line.rstrip() for line in open("file1") ]
lines2 = [ line.rstrip() for line in open("file2") ]
for i in xrange((len(lines1))): print lines1[i] + " ||| " + lines2[i]
... 
1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.