একই শিরোলেখ সহ একাধিক ফাইল সংহত করুন


26

আমার নীচে একই শিরোনাম এবং বিভিন্ন ভেক্টর সহ একাধিক ফাইল রয়েছে। আমি তাদের সকলকেই কনটেনেট করতে চাই তবে আমি চাই প্রথম ফাইলের কেবল শিরোনামই কনকানটেটেড করা হোক এবং আমি চাই না যে অন্যান্য শিরোনামগুলি একই রকম হয় কারণ তারা সমস্ত একই।

উদাহরণস্বরূপ: file1.txt

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B 
C

file2.txt

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E 
F

আমার আউটপুট দরকার

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E 
F

আমি আর স্ক্রিপ্ট লিখতে পারি তবে শেলটিতে আমার এটি দরকার?

উত্তর:


17

আপনি যদি এটি আর-তে কীভাবে করতে জানেন তবে সর্বদা এটি আর-তে করুন class ধ্রুপদী ইউনিক্স সরঞ্জাম সহ, এটি খুব স্বাভাবিকভাবেই বিশৃঙ্খলায় করা হয়।

awk '
    FNR==1 && NR!=1 { while (/^<header>/) getline; }
    1 {print}
' file*.txt >all.txt

অ্যাজক স্ক্রিপ্টের প্রথম লাইনটি কোনও ফাইলের প্রথম লাইনের সাথে মেলে ( FNR==1) যদি এটি সমস্ত ফাইলের ( NR==1) জুড়ে প্রথম লাইন হয় তবে । যখন এই শর্তগুলি পূরণ করা হয়, তখন এক্সপ্রেশনটি while (/^<header>/) getline;কার্যকর করা হয়, যার ফলে বর্তমানের রেজিএক্সপ্যাকের সাথে যতক্ষণ না মিলবে ততক্ষণ অন্য লাইনটি (বর্তমানটিকে এড়িয়ে যাওয়া) পড়া চালিয়ে যেতে পারে ^<header>। অ্যাজক স্ক্রিপ্টের দ্বিতীয় লাইনটি আগে স্কিপ করা লাইনগুলি বাদ দিয়ে সবকিছু মুদ্রণ করে।


ধন্যবাদ গিলস আমার প্রতিটি ফাইল জিবিতে রয়েছে। আর এটি করতে দক্ষ হবে না। ঐ জন্যই আমি জিজ্ঞাসা করেছিলাম.
জান্না

@ জনা কি এমন লাইন আছে যা শিরোনামের মতো দেখায় তবে ফাইলটির শীর্ষে নেই? যদি তা না হয় তবে দ্রুততম উপায়টি হ'ল grep( স্পুটনিকের উত্তরের মতো )।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

কোনও শিরোনামের লাইনগুলি সমস্ত ফাইলের মতো নয় এবং এগুলি প্রতিটি ফাইলের শীর্ষে রয়েছে। হ্যাঁ গ্রেপ দ্রুত ছিল। আপনাদের উভয়কে ধন্যবাদ
জান্না

1
@ জনা যাইহোক, যদি আপনার সমস্ত ফাইলের শিরোনামের সংখ্যা একই থাকে তবে এখানে অন্য একটি উপায় রয়েছে (যা আমি আরও দ্রুত হওয়ার প্রত্যাশা করি): head -n 10 file1.txt >output.txt && tail -q -n +11 file*.txt >>output.txt(যদি আপনার 10 টি শিরোলেখ থাকে)। এছাড়াও, যদি আপনার ফাইলগুলির নামগুলিতে নম্বর থাকে তবে সাবধান হন যে এবং এর file9.txtমধ্যে বাছাই করা আছে । আপনার ফাইল নম্বর পছন্দ যদি , ..., , , ..., তারপর তাদেরকে সঠিক অনুক্রমে তালিকা প্রস্তুত করা। file89.txtfile90.txtfile001.txtfiles009.txtfiles010.txtfiles*.txt
গিলস 'অশুভ হওয়া বন্ধ করুন'

একটি আরও ভাল সমাধান ( স্ট্যাকওভারফ্লো.com/ a/ 16890695/310441 থেকে ) যার জন্য রিজেক্স মিলের প্রয়োজন নেই: awk 'FNR==1 && NR!=1{next;}{print}' *.csv
ওভেন

42

cat+grepউপরে থেকে অনুরূপ অন্য একটি সমাধান, ব্যবহার tailএবং head:

  1. আউটপুটটিতে প্রথম ফাইলের শিরোনামটি লিখুন:

    head -2 file1.txt > all.txt

    - head -2ফাইলের 2 টি প্রথম লাইন পায়।

  2. সমস্ত ফাইলের সামগ্রী যুক্ত করুন:

    tail -n +3 -q file*.txt >> all.txt

    - -n +3তোলে tailশেষ 3 য় থেকে মুদ্রণ লাইন, -qবলা হয়েছে যে সব ফাইলের নাম (পড়ুন সঙ্গে হেডার প্রিন্ট করতে না man,) >>না যেমন মুছে ফেলা হয় ফাইলে যোগ করে, >

এবং নিশ্চিত যে আপনি উভয় কমান্ড এক লাইনে রাখতে পারেন:

head -2 file1.txt > all.txt; tail -n +3 -q file*.txt >> all.txt

অথবা পরিবর্তে সাফল্যের জন্য তাদের মধ্যে ;রাখা &&


3
আমি আরও সহজভাবে এটিতে পরামর্শ দিচ্ছি: (head -2 file1.txt ; tail -n +3 -q file*.txt ) > all.txtবা(head -2 file1.txt && tail -n +3 -q file*.txt ) > all.txt
হংবোঝু

4

এটি করার চেষ্টা করুন:

$ cat file1.txt; grep -v "^<header" file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B 
C
D
E 
F

বিঃদ্রঃ

  • -vপতাকা উপায়ে ম্যাচ উল্টানো
  • ^মধ্যে Regex , মানে স্ট্রিংয়ের শুরু
  • আপনার কাছে যদি গুচ্ছ ফাইল থাকে তবে আপনি এটি করতে পারেন

:

array=( files*.txt )
{ cat ${array[@]:0:1}; grep -v "^<header" ${array[@]:1}; } > new_file.txt

এটি একটি অ্যারে স্লাইসিং কৌশল।


ধন্যবাদ স্পটনিক, তবে আমার কাছে aten 30 ফাইল (file1.txt, file2.txt, file3.txt..filen.txt) জমে উঠতে হবে। আমার প্রতিটি ফাইলের নাম টাইপ করা উচিত বা এটি করার কোনও অন্য উপায় আছে?
জানা

স্লাইসিংয়ের কৌশল সহ আমার সম্পাদিত পোস্টটি দেখুন
গিলস কুইনট

এটি <header>কেবল শুরুতে নয়, ফাইলগুলির যে কোনও জায়গায় লাইনগুলি সরিয়ে দেয় । এটি এখানে কোনও সমস্যা হতে পারে না, তথ্যের উপর নির্ভর করে।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

1
grep '^<header>' file1.txt >output.txt && grep -v '^<header>' file*.txt >>output.txt
সরল

@Gilles: আমি অনেকদিন পর আপনার উত্তর লক্ষ্য কিন্তু এটা খুবই দরকারী ছিল
জানা

1

tailকমান্ড (গনুহ, অন্তত দিকে) প্রাথমিক লাইনের একটি প্রদত্ত সংখ্যার লাফালাফি করার জন্য একটি বিকল্প আছে। দ্বিতীয় লাইন থেকে পরবর্তী মুদ্রণ করতে, অর্থাৎ এক-লাইন শিরোনাম বাদ দিন, করুন:tail -n+2 myfile

সুতরাং, প্রথম ফাইলের দ্বি-লাইনের শিরোনামটি রাখুন তবে দ্বিতীয়টি নয়, বাশে:

cat file1.txt <(tail -n+3 file2.txt) > combined.txt

বা, অনেক ফাইলের জন্য:

head -n1 file1.txt > combined.txt
for fname in *.txt
do
    tail -n+3 $fname >> combined.txt
done

যদি কোনও নির্দিষ্ট স্ট্রিং সমস্ত শিরোলেখের লাইনে উপস্থিত থাকে তবে অন্য ইনপুট ফাইলগুলিতে কখনই উপস্থিত থাকে না, grep -vতবে স্পুটনিক দেখায় , এটি একটি সহজ পদ্ধতির।


1

এর সাথে সংক্ষিপ্ত (অগত্যা দ্রুত নয়) sed:

sed -e '3,${/^<header>/d' -e '}' file*.txt > all.txt

এটি <header>...3 লাইন থেকে শুরু করে সমস্ত লাইন মুছে ফেলবে , সুতরাং প্রথম শিরোনাম সংরক্ষণ করা হবে এবং অন্যান্য শিরোনামগুলি সরানো হবে। শিরোনামে ভিন্ন ভিন্ন লাইন থাকলে কমান্ডটি সেই অনুযায়ী সামঞ্জস্য করুন (উদাহরণস্বরূপ 7পরিবর্তে 6-লাইন শিরোনাম ব্যবহারের জন্য 3)।
শিরোনামে রেখার সংখ্যা অজানা থাকলে আপনি এটির মতো চেষ্টা করতে পারেন:

sed '1{
: again
n
/^<header>/b again
}
/^<header>/d
' file*.txt > all.txt

0

অ্যারে = (* .txt); হেড -1 $; অ্যারে [0]}> all.txt; লেজ -n +2 -কিউ $ {অ্যারে [@]: 0} >> all.txt

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


সামান্য ব্যাখ্যাটি ভবিষ্যতের ব্যবহারকারীদের সাহায্যের দিকে অনেক এগিয়ে যাবে
জেফ শ্যাচলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.