লিনাক্সে কোনও ফাইলের শেষ কলামটি কীভাবে মুছবেন


25

আমি একটি টেক্সট ফাইলের শেষ কলামটি মুছতে চাই, যখন কলাম নম্বরটি আমি জানি না। আমি এই কিভাবে করতে পারে?

উদাহরণ:

ইনপুট:

1223 1234 1323 ... 2222 123
1233 1234 1233 ... 3444 125
0000 5553 3455 ... 2334 222

এবং আমি আমার আউটপুটটি হতে চাই:

1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

এটি করার বিভিন্ন উপায় রয়েছে ... দয়া করে এটি থেকে একটি উদাহরণ এবং আপনার প্রত্যাশিত আউটপুট যুক্ত করুন ..
হিমাইল

@ হাইমাইল ঠিক আছে আমি করেছি
জারা

ধন্যবাদ..কলামগুলির ট্যাব পৃথক করা হয়েছে বা স্থান পৃথক করা আছে?
হিমাইল

@ হেইমাইল স্পেসটি সীমানা নির্ধারণকারী
জারা

উত্তর:


43

সাথে awk:

awk 'NF{NF-=1};1' <in >out

বা:

awk 'NF{NF--};1' <in >out

বা:

awk 'NF{--NF};1' <in >out

যদিও এটি ভুডোর মতো দেখায়, এটি কাজ করে। এই প্রতিটি অবাক কমান্ডের তিনটি অংশ রয়েছে।

প্রথমটি NF, যা দ্বিতীয় অংশের পূর্বশর্ত। NFএকটি লাইনে ক্ষেত্রের সংখ্যা সমেত একটি চলক। এডাব্লুকে-তে, জিনিসগুলি 0 বা খালি স্ট্রিং না হলে সত্য ""। সুতরাং, দ্বিতীয় অংশটি (যেখানে NFহ্রাস করা হয়) কেবল যদি NF0 হয় না তবে ঘটে ।

দ্বিতীয় অংশ (হয় NF-=1 NF--বা --NF) কেবল NFভেরিয়েবল থেকে একটি বিয়োগ করছে । এটি শেষ ক্ষেত্রটি মুদ্রণ হতে বাধা দেয়, কারণ আপনি যখন কোনও ক্ষেত্র পরিবর্তন করেন (এই ক্ষেত্রে শেষ ক্ষেত্রটি সরিয়ে ফেলবেন ), awkপুনর্নির্মাণ করুন $0, ডিফল্টরূপে স্পেস দ্বারা পৃথক করা সমস্ত ক্ষেত্রকে পুনরায় নির্মাণ করুন , সংযুক্ত করুন। $0শেষ ক্ষেত্রটি আর নেই।

চূড়ান্ত অংশ হয় 1। এটি যাদুকরী নয়, এটি কেবল একটি অভিব্যক্তি হিসাবে ব্যবহৃত হয়েছে যার অর্থ true। যদি কোনও awkঅভিব্যক্তি কোনও সম্পর্কিত ক্রিয়া ছাড়াই সত্যের কাছে মূল্যায়ন করে তবে awkডিফল্ট ক্রিয়া হয় print $0


@ জাজাও: আহ, ধন্যবাদ, ভুলে গেছি --। একটি নোট, বর্তমানে আপনার ;1পসিক্স অনুগত হওয়া দরকার ।
cuonglm

আমার প্রাথমিক প্রবৃত্তিটি লুপের জন্য ব্যবহার করা হবে তবে এটি আরও সংক্ষিপ্ত এবং চতুর।
সের্গেই কোলোডিয়াযনি

5
এটি লক্ষণীয় যে আপনি যদি একটি অ-ডিফল্ট ডিলিমিটার ব্যবহার করেন তবে আপনাকে কিছু পরিবর্তন করতে হবে। ধরে ,নেওয়া আপনার সীমানা:awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
মিঃ ল্লামা

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

16

grepপিসিআরই ব্যবহার করে :

$ grep -Po '.*(?=\s+[^\s]+$)' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

জিএনইউ ব্যবহার sed:

$ sed -r 's/(.*)\s+[^\s]+$/\1/' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

1
@ ইরামিন শিওর। আপনি কি দয়া করে এটি একটি নতুন প্রশ্ন হিসাবে জিজ্ঞাসা করুন (এটি এই সাইটটি কীভাবে কাজ করে) :)
হিমাইল

@ramin এটি কি আপনাকে কোনও সময়ের সীমাবদ্ধতা বা কোনও সতর্কতা দেয়?
হিমাইল

এটি বলে যে এটি স্ট্যান্ডার্ড প্রশ্নের বাইরে!
জারা

@ রামিন ওকে..আপনি আমাকে কোনও প্রশাসকের সাথে যোগাযোগ করুন, তারা কি এটির সাথে আপনাকে সহায়তা করতে পারে..তবে আপনি আপনার প্রশ্ন সম্পর্কিত কোনও পুরানো কিউএ পরীক্ষা করেছিলেন? এটি সম্ভবত একটি প্রশ্ন ইতিমধ্যে জিজ্ঞাসা করা হয়েছে এবং উত্তর দেওয়া হয়েছে ..
হিমাইল

3
" আমি কীভাবে লিনাক্সে ফাইলের নাম পরিবর্তন করতে পারি " এর মতো দুর্দান্ত বেসিক প্রশ্ন জিজ্ঞাসা করবেন না । গুগল ব্যবহার করুন।
ক্রিস্টোফার হ্যামারস্ট্রেম

11

পার্ল ব্যবহার:

perl -lane '$,=" ";pop(@F);print(@F)' in

ব্যবহার rev+ + cut:

rev in | cut -d ' ' -f 2- | rev

5

GNU সেড ব্যবহার:

sed -r 's/\s+\S+$//' input.txt

আরও সাধারণভাবে, এটি ওএসএক্সে বিএসডি সেডের পাশাপাশি জিএনইউ সেডের সাথে কাজ করে:

sed 's/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//' input.txt

1

যদি ডিলিমিটারটি সর্বদা একক চর হয় (সুতরাং দুই বা ততোধিক ক্রমান্বয়ে সীমানা খালি ক্ষেত্র নির্ধারণ করে), আপনি headআপনার ইনপুট ফাইল থেকে প্রথম লাইনটি, ডিলিমিটারগুলি গণনা করতে পারেন ( nসীমানার অর্থ ক্ষেত্রের সংখ্যা n+1) তবে স্ট্যান্ড ফিল্ড cutথেকে মুদ্রণের জন্য ব্যবহার করুন 1পর্যন্ত nতম ক্ষেত্র (দ্বিতীয় গত এক করা), ট্যাবের-সীমা নির্দেশ ইনপুট দিয়ে উদাহরণ:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l)
cut -f1-$n infile > outfile

অথবা যেমন একটি সিএসভি ফাইল সহ:

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l)
cut -d, -f1-$n infile > outfile

আমার কাছে সময় থাকলে আমি পরে কিছু বেঞ্চমার্ক চালাব তবে বিশাল ইনপুট সহ আমি মনে করি যে এই দ্রবণটি অন্যান্য সমাধানগুলির তুলনায় দ্রুত হওয়া উচিত যা রেগেক্স ব্যবহার করে কারণ এটি প্রথম নম্বরটিতে ন্যূনতম প্রক্রিয়াকরণ করে no ক্ষেত্র এবং তারপরে ব্যবহার করে cutযা এই কাজের জন্য অনুকূলিত।


1

বহনযোগ্যভাবে আপনি এই দুটি ব্যবহার করতে পারেন:

sed 's/[[:space:]]*[^[:space:]]*$//' file

awk '{sub(/[[:space:]]*[^[:space:]]*$/,"")}1' file

0

ভিএম ব্যবহার:

ভিএম ফাইল খুলুন

vim <filename> 

কার্সারটি অন্য কোথাও স্থাপন করা হলে, প্রথম সারিতে যান।

gg

"কিউ" নামের একটি ম্যাক্রো তৈরি করুন qqযা বর্তমান লাইনের $পিছনে যায়, তারপরে শেষ স্থানটিতে ফিরে যায় F(মূলধন এফ, যার পরে আক্ষরিক স্পেস থাকে) তারপরে লাইনের শেষের মধ্য দিয়ে বর্তমান অবস্থান থেকে মুছুন Dএবং পরবর্তী লাইনে চলে যান jএবং এর সাথে ম্যাক্রো রেকর্ডিং বন্ধ করুন q

qq$F Djq

এখন আমরা @qপ্রতিটি লাইনের সাথে আমাদের ম্যাক্রোর পুনরাবৃত্তি করতে পারি ।
আমরা @@শেষ ম্যাক্রো বা আরও সহজ পুনরাবৃত্তি করতে টিপতে পারি :

99@q

99 বার ম্যাক্রো পুনরাবৃত্তি।
দ্রষ্টব্য: সংখ্যাটি অবশ্যই লাইনের সাথে মেলে না।


0

যাদের ক্ষেত্রে একই সমস্যা রয়েছে তবে বিভিন্ন ফিল্ড বিভাজনকারীদের সাথে এই awkপদ্ধতিটি ফিল্ড বিভাজককে সঠিকভাবে সংরক্ষণ করবে:

$ cat file 
foo.bar.baz
baz.bar.foo
$ awk -F'.' 'sub(FS $NF,x)' file
foo.bar
baz.bar
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.