কোনও ফাইলের প্রতিটি নবম লাইন কীভাবে রাখবেন


71

আমি বরং একটি বড় আকারের সিএসভি ফাইল (75 এমবি) পেয়েছি। আমি কেবল এটির একটি গ্রাফ তৈরি করার চেষ্টা করছি, তাই সত্যই আমার সমস্ত ডেটার দরকার নেই।

পুনর্নির্মাণ: আমি এন লাইনগুলি মুছতে চাইছি, তারপরে একটি লাইন রাখি, তারপরে এন লাইনগুলি মুছুন, ইত্যাদি।

ফাইলটি যদি এমন দেখায়:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6

এবং n = 2, তারপরে আউটপুটটি হবে:

Line 3
Line 6

দেখে মনে হচ্ছে এটি এটি sedকরতে সক্ষম হবে তবে আমি কীভাবে তা বুঝতে পারি নি able একটি বাশ কমান্ডটি আদর্শ হতে পারে তবে আমি কোনও সমাধানের জন্য উন্মুক্ত।


2
আপনি কি 1, 4, 7, ইত্যাদির পরিবর্তে 1, 3, 6 ইত্যাদি লাইন চান?
ইলমারি করোনেন

2
যেহেতু এটি একটি সিএসভি ফাইল, আমি ধরে নিলাম প্রথম লাইনে মেটা ডেটা রয়েছে (যেমন ক্ষেত্রের নাম।)। যদি তা হয় তবে প্রশ্নটি "প্রথমটির পরে প্রতি নবম লাইন" হওয়া উচিত।
iglvzx

7
1, 3, 6 এখনও বোঝায় না!
উইম

1
আমি অনুমান করি যে এটি 1, 3, 5 হওয়া উচিত যদি না এন = 2 ত্রিভুজাকার সংখ্যার (1, 3, 6, 10, 15, 21 ইত্যাদি) এর যাদু মান না হয়
rjmunro

4
আপনি যা জিজ্ঞাসা করছেন ("প্রতি নবম লাইন", "এন = 2") এবং আপনার পছন্দসই আউটপুট (লাইন 3, লাইন 6) সামঞ্জস্য রেখে আপনি কী আপনার প্রশ্ন আপডেট করতে পারবেন? ভবিষ্যতের পাঠকরা বিভ্রান্ত হতে চলেছেন।
কিথ থম্পসন

উত্তর:


121
~ $ awk 'NR == 1 || NR % 3 == 0' yourfile
Line 1
Line 3
Line 6

NR(রেকর্ডের সংখ্যা) ভেরিয়েবল হ'ল লাইনের রেকর্ড সংখ্যা কারণ ডিফল্ট আচরণ RS(রেকর্ড পৃথক) এর জন্য নতুন লাইন । প্যাটার্ন এবং ক্রিয়া অজকের ডিফল্ট ফর্ম্যাটে isচ্ছিক 'pattern {actions}'। যখন আমরা কেবল প্যাটার্ন অংশ দেই তখন আমাদের প্যাটার্নের শর্তের জন্য awkসমস্ত ক্ষেত্র $0লিখি true


8
ডিফল্টদের জন্য ধন্যবাদ, আপনার এমনকি এতটা দরকার নেই:awk 'NR == 1 || NR % 3 == 0'
কেভিন

@ সেলম্যান: আপনি যদি কেভিনের সমাধানটি পছন্দ করেন তবে আপনি নিজের উত্তর আপডেট করার বিষয়টি বিবেচনা করতে পারেন।
কিথ থম্পসন

4
কেন এটি এমন করে বোঝানোর জন্য যত্নশীল? এইভাবে যদি কেউ এটি সামান্য
তাত্ক্ষণ

আমি দেখতে পেয়েছি যে এই পদ্ধতির ফলে আমার 1 এবং 2 টি লাইন ছেড়ে যায়। awk 'NR == 1 || NR % 2 == 0' myfile.txt | wc -lএকটি বিজোড় সংখ্যার ফলস্বরূপ এটি নিশ্চিত করা হয়েছে যখন মূল ফাইলটিতে লাইন সংখ্যা সমান ছিল। @ কেভ উত্তর আমার পরীক্ষার ক্ষেত্রে সবচেয়ে ভাল কাজ করে।
ড্যানিয়েল দা কুনহা

58

sed এটিও করতে পারেন:

$ sed -n '1p;0~3p' input.txt
Line 1
Line 3
Line 6

man sed~হিসাবে ব্যাখ্যা :

প্রথম ~ পদক্ষেপটি প্রথম ধাপের সাথে প্রথম শুরু করে প্রতিটি ধাপের লাইনটি মিলান। উদাহরণস্বরূপ, `` সেড-এন 1 ~ 2 পি '' ইনপুট স্ট্রিমের সমস্ত বিজোড়-সংখ্যাযুক্ত লাইনগুলি মুদ্রণ করবে এবং দ্বিতীয়টি দিয়ে শুরু করে 2 ~ 5 ঠিকানা প্রতি পঞ্চম লাইনে মিলবে। প্রথম শূন্য হতে পারে; এই ক্ষেত্রে, সেড এমনভাবে কাজ করে যা এটি পদক্ষেপের সমান। (এটি একটি এক্সটেনশন))


6
আপনি এই আদেশটি ব্যাখ্যা করতে পারেন?
কিড

1
@ কিয়েড ব্যাখ্যা: 1pপ্রথম লাইনটি 0~3pপ্রিন্ট করে , 3 য় লাইন থেকে শুরু করে প্রতি তৃতীয় লাইন প্রিন্ট করে ( 1pএভাবে লাইন 1 প্রিন্ট করা প্রয়োজন)। তবে মনে রাখবেন যে এটি 0~3স্ট্যান্ডার্ড নয় তবে একটি জিএনইউ সেড এক্সটেনশন।
আরক্কু

"এটি একটি এক্সটেনশন" " আপনি কোন সংস্করণটি ব্যবহার করছেন / করছেন?
ভিক্টর

উইন্ডোজ পাওয়ারশেলের জন্য এই উত্তরটি আমাকে অনেক সহায়তা করেছে। আমি এটি এর মতো আরও প্রশস্ত করেছি: sed -n '1p;0~10p' '.\in.txt' > out.txtহ্রাস হওয়া ফাইলটি আউটপুট-ফাইলে মুদ্রণ করতে।
কিমলিভ

22

পার্ল এটিও করতে পারে:

while (<>) {
    print  if $. % 3 == 1;
}

এই প্রোগ্রামটি তার ইনপুটটির প্রথম লাইনটি এবং তার পরে প্রতিটি তৃতীয় লাইন মুদ্রণ করবে।

এটির কিছুটা ব্যাখ্যা করার <>জন্য, লাইন ইনপুট অপারেটরটি, যখন লুপটিতে whileএই জাতীয় লুপ ব্যবহার করার সময় ইনপুট লাইনগুলির উপরে পুনরাবৃত্তি হয় । বিশেষ ভেরিয়েবলটিতে $.এখন পর্যন্ত পঠিত লাইনের সংখ্যা রয়েছে এবং %এটি মডুলাস অপারেটর।

এই কোডটি আরও ও নিবিড়ভাবে ওয়ান-লাইনার হিসাবে লেখা যেতে পারে, -nএবং -eসুইচগুলি ব্যবহার করে :

perl -ne 'print if $. % 3 == 1'  < input.txt  > output.txt

-eসুইচ, একটি কমান্ড লাইন প্যারামিটার হিসাবে চালানো পার্ল কোড এক টুকরা লাগে যখন -nসুইচ পরোক্ষভাবে একটি কোড গোপন whileউপরে দেখানো এক মত লুপ।


সম্পাদনা: আসলে উদাহরণ হিসাবে লাইন 1, 3, 6, 9, ... পেতে বরং লাইন 1, 4, 7, 10, চেয়ে ... যেমন আমি প্রথম অধিকৃত আপনি চেয়েছিলেন, প্রতিস্থাপন $. % 3 == 1সঙ্গে $. == 1 or $. % 3 == 0


7

আপনি যদি এটি কোনও বাশ স্ক্রিপ্ট দিয়ে করতে চান তবে আপনি চেষ্টা করতে পারেন:

#!/bin/sh

echo Please enter the file name
read fname
echo Please enter the Nth lines that you want to keep
read n

exec<$fname
value=0
while read line
do
    if [ $(( $value % $n )) -eq 0 ] ; then
        echo -e "$line" >> new_file.txt
    fi
        let value=value+1 
done
echo "Check the 'new_file.txt' that has been created in this directory";

এটিকে "read_lines.sh" হিসাবে সংরক্ষণ করুন এবং বাশ ফাইলে + x অনুমতি দেওয়ার কথা মনে রাখবেন।

chmod +x ./read_lines.sh

1
আপনি যদি স্ট্যান্ডার্ড আউট এ সবেমাত্র নির্গমন করেন তবে আর্গুমেন্ট থেকে এড়ানোর জন্য লাইনের সংখ্যাটি পড়ুন এবং স্ট্যান্ডার্ড ইন ফাইলটি পড়ুন, এটি সহজ এবং আরও কার্যকর হবে। আপনি এখনও করে new_file.txt তৈরি করতে পারেন ./read_lines.sh > new_file.txt
rjmunro

4

খাঁটি বাশের একটি সমাধান, যা কোনও প্রক্রিয়া উত্থাপন করে না:

{ for f in {1..2}; do read line; done;
  while read line; do
    echo $line;
    for f in {1..2}; do read line; done;
  done; } < file

প্রথম লাইনটি ফাইলের শুরুতে while2 টি লাইন ছেড়ে যায় এবং পরবর্তী লাইনে মুদ্রণ করে আবার 2 টি লাইন এড়িয়ে যায়।

আপনার ফাইলটি যদি ছোট হয় তবে এটি কাজটি করার খুব কার্যকরী উপায় কারণ এটি কোনও প্রক্রিয়া শুরু করে না। যখন আপনার ফাইলটি বড় হয়, sedআইও এর চেয়ে বেশি পরিচালনা করার ক্ষেত্রে এটি ব্যবহার করা উচিত bash


1

পাইথন সংস্করণ (পাইথন 2 এ পাইথন 3):

python2 -c "print(''.join(open('file.txt').readlines()[::3]))"

[::3]আরও নিয়ন্ত্রণের জন্য শুরু, শেষ এবং ধাপের আকারের পরামিতিগুলি প্রতিস্থাপন করুন । যেমন [10:36:5]10,15, ..., 35 লাইন রাখে out

দ্রষ্টব্য, যেহেতু readlines()লাইনটি শেষ করে রেখেছে , তাই এই কলটির আউটপুট খালি শেষ লাইনের সাথে শেষ হতে পারে, যদি না নির্বাচিত পদক্ষেপের আকারের মাধ্যমে মূল শেষ লাইনটি না ফেলে।

একটি স্ট্রিম সংস্করণও খুব সম্ভব (এখানে সমাপ্ত স্ট্রিমের পরে কেবল আউটপুট):

python -c "import sys;print(''.join(list(sys.stdin)[::3]))" < file.txt
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.