কোনও পাঠ্য ফাইলের লাইন থেকে নির্দিষ্ট শব্দগুলি কীভাবে সরিয়ে নেওয়া যায়?


13

আমার পাঠ্য ফাইলটি দেখতে এমন দেখাচ্ছে:

Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341

এখন আমি Liquid penetration 95% mass (m)মানগুলি পেতে আমার লাইনগুলি থেকে মুছতে চাই । আমি এটা কিভাবে করব?


3
কেবলgrep -o '[^[:space:]]\+$' file
অবিনাশ রাজ

@ অবিনাশরাজ: এই মুহুর্তে, এই সমাধানটি 'পুট্টি পদক'
পেয়েছে

2
@ pa4080 অন্তত আমি পরীক্ষিত ইনপুটটির জন্য (10 এম লাইন), অবিনাশ রাজের সাধারণ পদ্ধতির পিসিআরই ব্যবহার করে দ্রুততর আকারের অর্ডার তৈরি করা যেতে পারে। (আমি নিশ্চিত করতে পারে যে ইঞ্জিন, না প্যাটার্ন, দায়ী গনুহ, grep গ্রহণ যেমন \S+$পারেন সঙ্গে -Eবা -P।) সুতরাং সমাধান এই ধরনের মজ্জাগতভাবে ধীর নয়। কিন্তু আমি এখনও এটা কোথাও ঘনিষ্ঠ পেতে পারেন αғsнιη এর cutপদ্ধতি , যা আপনার বেঞ্চমার্ক জিতেছে খুব।
এলিয়াহ কাগন 21

উত্তর:


22

যদি কেবল একটি =চিহ্ন থাকে তবে আপনি আগে এবং এর =মতো সমস্ত কিছু মুছতে পারেন:

$ sed -r 's/.* = (.*)/\1/' file
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

আপনি যদি আসল ফাইলটি পরিবর্তন করতে চান তবে -iপরীক্ষার পরে বিকল্পটি ব্যবহার করুন :

sed -ri 's/.* = (.*)/\1/' file

মন্তব্য

  • -rআগে ব্যবহার করুন যাতে আমাদের পালাতে হবে না (এবং)
  • s/old/newoldসঙ্গে প্রতিস্থাপনnew
  • .* যে কোনও অক্ষরের সংখ্যা
  • (things)সংরক্ষণ thingsপরে backreference করতে \1, \2ইত্যাদি

ধন্যবাদ এটি কাজ করেছে। আমি এই আদেশটি বিদ্যমান ফাইলটি ওভাররাইট করতে ব্যবহার করেছি: sed -i -r 's /.*= (। *) / \ 1 /' time.txt আপনি কীভাবে এটি কাজ করে তা ব্যাখ্যা করতে পারেন?
ওই

পিছনে পিছনে কেন এড়াবেন না? s/^.*= //সমানভাবে ভাল কাজ করবে, যেহেতু সঠিক মান লাইনের শেষে রয়েছে।
jpaugh

@jpaugh আংশিকভাবে কারণ আমার উত্তরটি পরিবর্তন করতে খুব দেরি হয়েছে যা প্রথম পোস্ট হয়েছিল - অন্যরা ইতিমধ্যে আপনার উল্লেখ করা সমাধান এবং এই মামলার জন্য আরও কার্যকর উপায় দিয়েছে :) তবে সম্ভবত কীভাবে \1ইত্যাদি ব্যবহার করবেন তা দেখানো মানুষের জন্য কিছু মূল্য রয়েছে অনুসন্ধান করার সময় এই প্রশ্নের
অবতারণ করুন

@ জান্না এটি আরও সাধারণ, কমপক্ষে।
jpaugh

21

এটি একটি কাজ awk; ধরে নিচ্ছি মানগুলি সর্বশেষ ক্ষেত্রের মধ্যে ঘটে (কেবল আপনার উদাহরণ হিসাবে):

awk '{print $NF}' file.txt
  • NFএকটি awkপরিবর্তনশীল, একটি রেকর্ডে (ক্ষেত্রের) ক্ষেত্রের সংখ্যায় প্রসারিত, সুতরাং $NF( $সামনের দিকে দ্রষ্টব্য ) শেষ ক্ষেত্রের মান ধারণ করে।

উদাহরণ:

% cat temp.txt 
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341

% awk '{print $NF}' temp.txt
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

13

আমি এখানে তালিকাভুক্ত বিভিন্ন সমাধানগুলির সাথে তুলনা করার সিদ্ধান্ত নিয়েছি। এই উদ্দেশ্যে আমি ওপি দ্বারা সরবরাহিত সামগ্রীর উপর ভিত্তি করে একটি বড় ফাইল তৈরি করেছি:

  1. আমি একটি সাধারণ ফাইল তৈরি করেছি, যার নাম input.file:

    $ cat input.file
    Liquid penetration 95% mass (m) = 0.000205348
    Liquid penetration 95% mass (m) = 0.000265725
    Liquid penetration 95% mass (m) = 0.000322823
    Liquid penetration 95% mass (m) = 0.000376445
    Liquid penetration 95% mass (m) = 0.000425341
    
  2. তারপরে আমি এই লুপটি কার্যকর করেছি:

    for i in {1..100}; do cat input.file | tee -a input.file; done
    
  3. টার্মিনাল উইন্ডো অবরুদ্ধ ছিল। আমি killall teeঅন্য টার্মিনাল থেকে মৃত্যুদন্ড কার্যকর করেছি । তারপরে আমি কমান্ডগুলি দ্বারা ফাইলটির সামগ্রীটি পরীক্ষা করেছিলাম: less input.fileএবং cat input.file। এটি শেষ লাইনটি বাদে ভাল লাগছিল। সুতরাং আমি শেষ লাইনটি সরিয়ে নিয়েছি এবং একটি ব্যাকআপ অনুলিপি তৈরি করেছি: cp input.file{,.copy}(অন্তর্ভুক্ত বিকল্পগুলি ব্যবহার করা আদেশগুলির কারণে )।

  4. ফাইলে লাইন চূড়ান্ত গণনা input.fileহয় 2 192 473 । কমান্ড দ্বারা আমি এই নম্বর পেয়েছি wc:

    $ cat input.file | wc -l
    2192473
    

এখানে তুলনার ফলাফল:

  • grep -o '[^[:space:]]\+$'

    gre সময় গ্রেপ -o '[^ [: স্থান:]] \ + $' ইনপুট.ফাইল> আউটপুট.ফাইল
    
    বাস্তব 0m58.539s
    ব্যবহারকারী 0m58.416s
    sys 0m0.108s
    
  • sed -ri 's/.* = (.*)/\1/'

    $ সময় সেড -ri 's /.* = (। *) / \ 1 /' ইনপুট.ফাইল
    
    আসল 0m26.936s
    ব্যবহারকারী 0m22.836s
    sys 0m4.092s
    

    বিকল্প হিসাবে যদি আমরা আউটপুটটিকে একটি নতুন ফাইলে পুনর্নির্দেশ করি তবে কমান্ডটি আরও দ্রুত:

    $ সময় সেড-আর 's /.* = (। *) / \ 1 /' ইনপুট.ফাইল> আউটপুট.ফাইল
    
    আসল 0m19.734s
    ব্যবহারকারী 0m19.672s
    sys 0m0.056s
    
  • gawk '{gsub(".*= ", "");print}'

    $ টাইম গাওক '{gsub ("। * =", ""); প্রিন্ট করুন}' ইনপুট.ফাইল> আউটপুট.ফাইল
    
    বাস্তব 0m5.644s
    ব্যবহারকারী 0m5.568s
    sys 0m0.072s
    
  • rev | cut -d' ' -f1 | rev

    $ সময় রেভ ইনপুট.ফাইল | কাট-ডি '' -ফ 1 | rev> আউটপুট.ফাইল
    
    আসল 0m3.703 এস
    ব্যবহারকারী 0m2.108s
    ss 0m4.916s
    
  • grep -oP '.*= \K.*'

    $ সময় গ্রেপ-ওপি '। * = \ কে। *' ইনপুট.ফাইল> আউটপুট.ফাইল
    
    বাস্তব 0m3.328s
    ব্যবহারকারী 0m3.252 এস
    sys 0m0.072s
    
  • sed 's/.*= //' (যথাক্রমে -iবিকল্পটি কমান্ডটি কয়েকগুণ কমিয়ে দেয়)

    $ সময় সেড 's /.*= //' ইনপুট.ফাইলে> আউটপুট.ফাইল
    
    বাস্তব 0m3.310s
    ব্যবহারকারী 0m3.212 এস
    sys 0m0.092s
    
  • perl -pe 's/.*= //' ( -iবিকল্পটি এখানে উত্পাদনশীলতায় বড় পার্থক্য আনতে পারে না)

    $ সময় পার্ল- i.bak -pe 's /.*= //' ইনপুট.ফাইল
    
    বাস্তব 0m3.187s
    ব্যবহারকারী 0m3.128s
    sys 0m0.056s
    
    $ টাইম পার্ল -পি 'এর /.*= //' ইনপুট.ফাইল> আউটপুট.ফাইল
    
    বাস্তব 0m3.138s
    ব্যবহারকারী 0m3.036s
    sys 0m0.100s
    
  • awk '{print $NF}'

    $ টাইম অজানা '{প্রিন্ট করুন $ এনএফ}' ইনপুট.ফিল> আউটপুট.ফাইল
    
    বাস্তব 0m1.251s
    ব্যবহারকারী 0m1.164s
    sys 0m0.084s
    
  • cut -c 35-

    $ সময় কাটা -c 35- ইনপুট.ফাইল> আউটপুট.ফাইল
    
    বাস্তব 0m0.352 এস
    ব্যবহারকারী 0m0.284s
    sys 0m0.064s
    
  • cut -d= -f2

    $ সময় কাটা -d = -f2 ইনপুট.ফাইল> আউটপুট.ফাইল
    
    আসল 0m0.328s
    ব্যবহারকারী 0m0.260s
    sys 0m0.064s
    

ধারণার উত্স।


2
সুতরাং আমার cut -d= -f2সমাধান জেতে হাহা
সু

আপনি কীভাবে এই ফাইলটি তৈরি করেছেন সে সম্পর্কে আরও তথ্য দিতে পারেন? এছাড়াও, wc -lতিনটি আউটপুট কিভাবে হয় ? যখন অন্য কোনও বিকল্প পাস না করা হয়, -lঅপশনটিতে লাইন গণনা ব্যতীত সমস্ত কিছুই দমন করা উচিত।
এলিয়াহ

এলিয়াকাগান, সম্পন্ন আমি উত্তর আপডেট করেছি।
pa4080

আহ, আমি দেখছি - স্পেসগুলি ডিজিটাল গ্রুপ বিভাজক ছিল। ( wcআসলে এই জায়গাগুলি প্রদর্শিত হয়েছিল? লোকেল সেটিংস রয়েছে যার জন্য এটি এটি করবে?) আপডেটের জন্য ধন্যবাদ!
এলিয়াহ

@ এলিয়াকাগান: অবশেষে আমি আপনার প্রশ্নগুলি wcআরও একবার পড়ি । আমি জানি না যে আমার আজকের প্রথম দিকের বুদ্ধিগুলি কোথায় ছিল, কিন্তু আমি সত্যিই সেগুলি বুঝতে পারি না। সুতরাং প্রকৃতপক্ষে স্পেসগুলিwc
ডিজিটাল

12

সঙ্গে grepএবং -Pথাকার জন্য PCRE(ক যেমন প্যাটার্ন ব্যাখ্যা পি erl- সি ompatible আর egular এবং অনুভূতির) -oপ্রিন্ট করতে মিলেছে প্যাটার্ন একা। \Kমিলেছে অংশ নিজেই আগে আসবে উপেক্ষা করা হবে অবহিত করুন।

$ grep -oP '.*= \K.*' infile
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

অথবা আপনি cutপরিবর্তে কমান্ড ব্যবহার করতে পারে ।

cut -d= -f2 infile

2
চলমান ছাড়াও পরীক্ষিত সকল পদ্ধতির দ্রুততম pa4080 এর বেঞ্চমার্ক , এই উত্তর পদ্ধতি এছাড়াও স্পষ্ট বিজয়ী একটি ছোট বেঞ্চমার্ক আমি দৌড়ে যে পরীক্ষিত কম পদ্ধতি কিন্তু একটি বৃহত্তর ইনপুট ফাইল ব্যবহার করা হয়েছে। আমি ব্যক্তিগতভাবে যে পদ্ধতিটি পছন্দ করি তার দ্রুততম পরিবর্তনের চেয়ে দশগুণ বেশি দ্রুত ছিল (এবং আমার উত্তরটি মূলত এটি সম্পর্কে)। cut
এলিয়াহ কাগন 21

11

যেহেতু লাইন উপসর্গটিতে সর্বদা একই দৈর্ঘ্য (34 টি অক্ষর) থাকে আপনি ব্যবহার করতে পারেন cut:

cut -c 35- < input.txt > output.txt

6

ফাইলের সামগ্রীটি এর সাথে বিপরীত করুন rev, আউটপুটটিকে cutডিলিমিটার হিসাবে এবং লক্ষ্য ক্ষেত্র হিসাবে 1 হিসাবে আউটপুটটি পাইপ করুন , তারপরে মূল নম্বরটি পেতে এটি আবার বিপরীত করুন:

$ rev your_file | cut -d' ' -f1 | rev
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

5

এটি সহজ, সংক্ষিপ্ত এবং সহজেই লেখা, বুঝতে এবং পরীক্ষা করা সহজ এবং আমি ব্যক্তিগতভাবে এটি পছন্দ করি:

grep -oE '\S+$' file

grepউবুন্টুতে , যখন শ্বেতস্পেসের অক্ষর বোঝায় -Eবা ব্যবহার করা হয় তখন শর্টহ্যান্ড-P গ্রহণ করে ( সাধারণত বাস্তবে কোনও স্থান বা ট্যাব থাকে) এবং এমন কোনও কিছু বোঝায় যা একটি নয়। কোয়ান্টিফায়ার এবং লাইনটির শেষ প্রান্তটি ব্যবহার করে , প্যাটার্নটি একটি লাইনের শেষে এক বা একাধিক অ-ফাঁকা সাথে মেলে । আপনি এর পরিবর্তে ব্যবহার করতে পারেন ; এই ক্ষেত্রে অর্থটি একই তবে ভিন্ন নিয়মিত এক্সপ্রেশন ইঞ্জিন ব্যবহৃত হয়, তাই তাদের বিভিন্ন কার্যকারিতা বৈশিষ্ট্য থাকতে পারে \s\S+$\S+$-P-E

এটি অবিনাশ রাজের মন্তব্যযুক্ত সমাধানের সমান (কেবল একটি সহজ, আরও কমপ্যাক্ট সিনট্যাক্স সহ):

grep -o '[^[:space:]]\+$' file

সংখ্যার পরে যদি পূর্ববর্তী সাদা স্থান থাকতে পারে তবে এই পদ্ধতিগুলি কাজ করবে না । তারা তাই করে তাদের পরিবর্তন করা যেতে পারে, তবে আমি এখানে intoোকানোর কোনও অর্থ দেখছি না। যদিও এটি বেশিরভাগ ক্ষেত্রে অধীনে কাজ করার সমাধানকে সাধারণীকরণ করার জন্য নির্দেশমূলক, তবুও প্রায়শই লোকেরা ধারনা করে এমনটি করা প্রায়শই বাস্তব নয়, কারণ সমস্যাটি শেষ পর্যন্ত অনেকগুলি বেমানান উপায়গুলির মধ্যে কোনটি জানার উপায় নেই যা সাধারণত শেষ পর্যন্ত প্রয়োজন might সাধারণীকরণ করা।


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

$ perl -e 'print((<>) x 2000000)' file > bigfile
$ du -sh bigfile
439M    bigfile
$ wc -l bigfile
10000000 bigfile
$ TIMEFORMAT=%R
$ time grep -o '[^[:space:]]\+$' bigfile > bigfile.out
819.565
$ time grep -oE '\S+$' bigfile > bigfile.out
816.910
$ time grep -oP '\S+$' bigfile > bigfile.out
67.465
$ time cut -d= -f2 bigfile > bigfile.out
3.902
$ time grep -o '[^[:space:]]\+$' bigfile > bigfile.out
815.183
$ time grep -oE '\S+$' bigfile > bigfile.out
824.546
$ time grep -oP '\S+$' bigfile > bigfile.out
68.692
$ time cut -d= -f2 bigfile > bigfile.out
4.135

অর্ডার ম্যাটার হয়ে যাওয়ার ক্ষেত্রে আমি এটি দু'বার চালিয়েছি (কারণ এটি কখনও কখনও I / O- ভারী কাজের জন্য হয়) এবং কারণ আমার কাছে এমন কোনও মেশিন নেই যা ব্যাকগ্রাউন্ডে অন্য জিনিসগুলি করছিল না যা ফলাফলগুলি আঁকিয়ে ফেলতে পারে। এই ফলাফলগুলি থেকে আমি নিম্নলিখিতটি শেষ করি, কমপক্ষে সাময়িকভাবে এবং আমি ব্যবহৃত আকারের ইনপুট ফাইলগুলির জন্য:

  • কি দারুন! পাসিং -P( পিসিআরই ব্যবহারের জন্য ) পরিবর্তে -G(কোনও ডায়ালেক্ট নির্দিষ্ট না করা হলে ডিফল্ট) বা প্রস্থের অর্ডারে দ্রুত -Eতৈরি করা grepহয়। সুতরাং বড় ফাইলগুলির জন্য, এই কমান্ডটি উপরের প্রদর্শিত আদেশের চেয়ে ব্যবহার করা ভাল:

    grep -oP '\S+$' file
  • কি দারুন!! cutপদ্ধতি αғsнιη এর উত্তর , , এমনকি আমার পথ থেকে দ্রুততর সংস্করণের তুলনায় দ্রুততর মাত্রার একটি আদেশ শেষ! এটি Pa4080 এর বেঞ্চমার্কেও বিজয়ী ছিল , যা এর চেয়ে আরও বেশি পদ্ধতিগুলি কভার করেছিল তবে ছোট ইনপুট সহ - এবং এই কারণেই আমি আমার পরীক্ষায় অন্তর্ভুক্ত করার জন্য অন্যান্য সমস্ত পদ্ধতির মধ্যে এটি বেছে নিয়েছিলাম। যদি পারফরম্যান্স গুরুত্বপূর্ণ হয় বা ফাইলগুলি বিশাল হয় তবে আমি মনে করি এর পদ্ধতিটি ব্যবহার করা উচিত।cut -d= -f2 filecut

    এটি একটি অনুস্মারক হিসাবেও কাজ করে যে সহজ cutএবং pasteইউটিলিটিগুলি ভুলে যাওয়া উচিত নয় এবং প্রযোজ্য ক্ষেত্রে সম্ভবত পছন্দ করা উচিত, যদিও এর মতো আরও পরিশীলিত সরঞ্জামগুলি grepপ্রায়শই প্রথম সারির সমাধান হিসাবে দেওয়া হয় (এবং আমি ব্যক্তিগতভাবে আরও অভ্যস্ত ব্যবহার করে)।


4

perl- গুলি প্যাটার্ন ubstitute /.*= /খালি স্ট্রিং সঙ্গে //:

perl -pe 's/.*= //' input.file > output.file
perl -i.bak -pe 's/.*= //' input.file
  • থেকে perl --help:

    -e program        one line of program (several -e's allowed, omit programfile)
    -p                assume loop like -n but print line also, like sed
    -i[extension]     edit <> files in place (makes backup if extension supplied)
    

sed - খালি স্ট্রিংয়ের সাথে প্যাটার্নটি প্রতিস্থাপন করুন:

sed 's/.*= //' input.file > output.file

বা (তবে উপরের চেয়ে ধীর) :

sed -i.bak 's/.*= //' input.file
  • আমি এই পদ্ধতির উল্লেখ করছি, কারণ এটি জানার উত্তরের চেয়ে কয়েকগুণ দ্রুত ।

gawk- ".*= "খালি স্ট্রিংয়ের সাথে প্যাটার্নটি প্রতিস্থাপন করুন "":

gawk '{gsub(".*= ", "");print}' input.file > output.file
  • থেকে man gawk:

    gsub(r, s [, t]) For each substring matching the regular expression r in the string t,
                     substitute the string s, and return the number of substitutions. 
                     If t is not supplied, use $0...
    
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.