বাশ - ফাইলের প্রতিটি লাইন জোড়া


10

এই প্রশ্নটি এই এবং এই প্রশ্নের সাথে দৃ strongly়ভাবে সম্পর্কিত । আমার একটি ফাইল রয়েছে যাতে বেশ কয়েকটি লাইন রয়েছে যেখানে প্রতিটি লাইন একটি ফাইলের পথ। এখন আমি প্রতিটি লাইন প্রতিটি পৃথক লাইনের সাথে জুড়ে রাখতে চাই (নিজেই নয়)। এছাড়াও আমার উদ্দেশ্যগুলির জন্য A Bএকটি B Aজোড়া একটি জোড়ার সমান , সুতরাং এই সংমিশ্রণের মধ্যে কেবল একটিরই উত্পাদন করা উচিত।

উদাহরণ

files.dat একটি সংক্ষিপ্ত স্বরলিপি এই মত পড়া, প্রতিটি অক্ষর একটি ফাইল পাথ (পরম বা আপেক্ষিক)

a
b
c
d
e

তারপরে আমার ফলাফলটি এমন কিছু দেখা উচিত:

a b
a c
a d
a e
b c
b d
b e
c d
c e
d e

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


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

বাফ কমান্ডলাইনের সাহায্যে @ জেফশালার কিছু অ্যাক্সেসযোগ্য। আমি কিছুটা অস্পষ্ট ছিলাম, দুঃখিত
এন্নো

এটি প্রায় একটি কোড গল্ফ হয়ে উঠছে : পি
রিচার্ড ডি উইট

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

উত্তর:


7

এই আদেশটি ব্যবহার করুন:

awk '{ name[$1]++ }
    END { PROCINFO["sorted_in"] = "@ind_str_asc"
        for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
        ' files.dat

PROCINFOএকটি gawkএক্সটেনশন হতে পারে । যদি awkএটি সমর্থন করে না, কেবল PROCINFO["sorted_in"] = "@ind_str_asc"রেখাটি ছেড়ে দিন এবং আউটপুটটি পাইপ করুন sort(যদি আপনি আউটপুটটি সাজান চান)।

(এর জন্য ইনপুটটি বাছাই করার প্রয়োজন হয় না ))


8
$ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e

এটি ধরে নিয়েছে যে ইনপুট ফাইলের কোনও লাইনে কোনও সাদা স্থান নেই। এটি ধরেও নেয় যে ফাইলটি বাছাই করা হয়েছে

joinকমান্ড ফাইলে লাইনের পূর্ণ ক্রস পণ্য তৈরি করে। এটি কোনও অ-বিদ্যমান ক্ষেত্রে নিজের সাথে ফাইলটিতে যোগদান করে এটি করে। অ-মানকটি -j 2দ্বারা প্রতিস্থাপিত হতে পারে -1 2 -2 2( -j2তবে আপনি জিএনইউ ব্যবহার না করে তবে নয় join)।

awkকমান্ড এর ফলে পড়ে এবং শুধুমাত্র ফলাফল জোড়া হয়েছে যে এখনো দেখা হয় আউটপুট।


"ফাইলটি বাছাই করা" বলতে আপনার অর্থ কী? কোন মানদণ্ড অনুসারে সাজানো?
এন্নো

@ এন্নো sort -bবাছাই করা পথটি এটি বাছাই করবে। joinবাছাই করা ইনপুট ফাইলগুলির প্রয়োজন।
কুসালানন্দ

8

একটি pythonসমাধান। ইনপুট ফাইলটিকে itertools.combinationsস্ট্যান্ডার্ড লাইব্রেরি থেকে খাওয়ানো হয় , যা 2-দৈর্ঘ্যের টিপলগুলি উত্পন্ন করে যা ফর্ম্যাট হয় এবং স্ট্যান্ডার্ড আউটপুটে মুদ্রিত হয়।

python3 -c 'from itertools import combinations
with open("file") as f:
    lines = (line.rstrip() for line in f)
    lines = ("{} {}".format(x, y) for x, y in combinations(lines, 2))
    print(*lines, sep="\n")
'

6

আপনি rubyইনস্টল করা থাকলে:

$ ruby -0777 -F'\n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
  • -0777 পুরো ফাইল স্লাপ করুন (ওপিতে যেমন উল্লেখ করা হয়েছে ঠিকঠাক হওয়া উচিত যে ফাইলের আকার ছোট)
  • -F'\n'নিউলাইন উপর ভিত্তি করে বিভক্ত, সুতরাং প্রতিটি লাইন $Fঅ্যারে একটি উপাদান হবে
  • $F.combination(2)2একসাথে সংমিশ্রণের উপাদান তৈরি করুন
  • { |c| puts c.join(" ")} প্রয়োজনীয় হিসাবে মুদ্রণ
  • যদি ইনপুট ফাইলটিতে নকল থাকতে পারে তবে ব্যবহার করুন $F.uniq.combination(2)


একসাথে 3 টি উপাদানের জন্য:

$ ruby -0777 -F'\n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
a b c
a b d
a b e
a c d
a c e
a d e
b c d
b c e
b d e
c d e


সাথে perl(জেনেরিক নয়)

$ perl -0777 -F'\n' -lane 'for $i (0..$#F) {
                             for $j ($i+1..$#F) { 
                               print "$F[$i] $F[$j]\n" } }' ip.txt
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e


সঙ্গে awk

$ awk '{ a[NR]=$0 }
       END{ for(i=1;i<=NR;i++)
              for(j=i+1;j<=NR;j++)
                print a[i], a[j] }' ip.txt 
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e

5

খাঁটি শেলের মধ্যে একটি এখানে।

test $# -gt 1 || exit
a=$1
shift
for f in "$@"
do
  echo $a $f
done
exec /bin/sh $0 "$@"

উদাহরণ:

~ (137) $ sh test.sh $(cat file.dat)
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
~ (138) $ 

1
কমান্ড প্রতিস্থাপন স্ট্রাইপগুলি নতুন <file.dat xargs test.shtest.sh $(cat file.dat)
লাইনের

1

ব্যবহার হিসাবে Perlআমরা প্রদর্শিত হিসাবে এটি করতে পারেন:

$ perl -lne '
     push @A, $_}{
     while ( @A ) {
        my $e = shift @A;
        print "$e $_" for @A;
     }
' input.txt
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.