আমি কীভাবে লাইন ভিত্তিতে একটি লাইনে ফাইলগুলিকে মার্জ করতে পারি?


22

বিড়াল ফাইল 1

foo
ice
two

বিড়াল ফাইল 2

bar
cream
hundred

পছন্দসই আউটপুট:

foobar
icecream
twohundred

ফাইল 1 এবং ফাইল 2 এর ক্ষেত্রে আমার দৃশ্যে সর্বদা একই পরিমাণের লাইন থাকবে, যদি বিষয়গুলি সহজ করে তোলে।

উত্তর:


34

সম্ভবত এই কাজের জন্য সঠিক সরঞ্জাম paste

paste -d '' file1 file2

দেখুন man pasteবিস্তারিত জানার জন্য।


আপনি prকমান্ডটি ব্যবহার করতে পারেন :

pr -TmJS"" file1 file2

কোথায়

  • -T পৃষ্ঠাগুলি বন্ধ করে দেয়
  • -mJ মি আরজি ফাইলস, জে অয়েলিং সম্পূর্ণ লাইন
  • -S"" খালি স্ট্রিং দিয়ে কলামগুলি পৃথক করুন

আপনি যদি সত্যিই খাঁটি বাশ শেল ব্যবহার করে এটি করতে চেয়েছিলেন (প্রস্তাবিত নয়) তবে আমি এটিই পরামর্শ দেব:

while IFS= read -u3 -r a && IFS= read -u4 -r b; do 
  printf '%s%s\n' "$a" "$b"
done 3<file1 4<file2

(কেবলমাত্র এটি অন্তর্ভুক্ত করার কারণে বিষয়টি অন্য প্রস্তাবিত খাঁটি-বাশ সমাধানের মন্তব্যে এসেছিল))


1
দুর্দান্ত, খুব সহজ সমাধানের জন্য আপনাকে ধন্যবাদ। পেস্টটি ব্যবহার করার ক্ষেত্রে আমার কি কখনই বহনযোগ্যতা নিয়ে চিন্তা করা উচিত?
টাক্সফোর্ডলাইফ

1
@ user264974 পেস্টটি GNU Coreutils এ রয়েছে তাই আপনি সম্ভবত মোটামুটি নিরাপদ।
নেটটাক্স

8

উপায় মাধ্যমে :

awk '{getline x<"file2"; print $0x}' file1
  • getline x<"file2"ফাইল 2 থেকে পুরো লাইনটি পড়ে এবং এক্স ভেরিয়েবলের মধ্যে রয়েছে।
  • print $0xথেকে পুরো লাইন ছাপে file1 ব্যবহার করে $0তারপর xযার সংরক্ষিত লাইন file2

একটি awk বিকল্প পেয়ে খুব ভাল, আমি পরিবর্তে এটি ব্যবহার করতে পারেন!
টাকসফোরলাইফ

4

pasteযেতে উপায় । আপনি যদি কিছু অন্যান্য পদ্ধতি পরীক্ষা করতে চান তবে এখানে একটি pythonসমাধান দিন:

#!/usr/bin/env python2
import itertools
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    lines = itertools.izip_longest(f1, f2)
    for a, b in lines:
        if a and b:
            print a.rstrip() + b.rstrip()
        else:
            if a:
                print a.rstrip()
            else:
                print b.rstrip()

আপনার কয়েকটি সংখ্যক লাইন থাকলে:

#!/usr/bin/env python2
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    print '\n'.join((a.rstrip() + b.rstrip() for a, b in zip(f1, f2)))

নোট করুন যে অসম সংখ্যক লাইনের জন্য, এটি প্রথমে শেষ হওয়া ফাইলটির শেষ লাইনে শেষ হবে।


3

এছাড়াও, খাঁটি সাথে bash(লক্ষ্য করুন এটি খালি লাইনগুলি পুরোপুরি উপেক্ষা করবে):

#!/bin/bash

IFS=$'\n' GLOBIGNORE='*'
f1=($(< file1))
f2=($(< file2))
i=0
while [ "${f1[${i}]}" ] && [ "${f2[${i}]}" ]
do
    echo "${f1[${i}]}${f2[${i}]}" >> out
    ((i++))
done
while [ "${f1[${i}]}" ]
do
    echo "${f1[${i}]}" >> out
    ((i++))
done
while [ "${f2[${i}]}" ]
do
    echo "${f2[${i}]}" >> out
    ((i++))
done

এটি কেবল সাধারণ ভুল। এটি মোটেই কাজ করে না। হয় mapfileফাইলগুলিকে অ্যারেতে পড়তে ব্যবহার করুন বা দুটি readকমান্ডের সাহায্যে কিছুক্ষণ লুপ ব্যবহার করুন , প্রতিটি তাদের এফডি থেকে পড়া।
গিরিহা

@ গিরিহা আপনি ঠিক বলেছেন, আমি সিনট্যাক্স নিয়ে গণ্ডগোল করেছি, এখন ঠিক আছে।
কোস

বেশ না। আপডেট হওয়া কোডের সাথে খালি লাইন উপেক্ষা করা হবে এবং যদি কোনও লাইনে গ্লোব অক্ষর থাকে তবে লাইনটি ফাইলের নামের সাথে মিলে যায়। সুতরাং কখনও ব্যবহার array=( $(cmd) )বা array=( $var )mapfileপরিবর্তে ব্যবহার করুন।
গিরিহা

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

2

পার্ল উপায়, বুঝতে সহজ:

#!/usr/bin/perl
$filename1=$ARGV[0];
$filename2=$ARGV[1];

open(my $fh1, "<", $filename1) or die "cannot open < $filename1: $!";
open(my $fh2, "<", $filename2) or die "cannot open < $filename2: $!";

my @array1;
my @array2;

while (my $line = <$fh1>) {
  chomp $line;
  push @array1, $line;
}
while (my $line = <$fh2>) {
  chomp $line;
  push @array2, $line;
}

for my $i (0 .. $#array1) {
  print @array1[$i].@array2[$i]."\n";
}

শুরু করা:

./merge file1 file2

আউটপুট:

foobar
icecream
twohundred
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.