একটি ফাইলের প্রতিটি অক্ষরের সংখ্যা গণনা করার দ্রুততম উপায় কী?


121

আমি একটি ফাইলের এ এর ​​টি এর সি এর জি এর এন এবং "-" অক্ষর, বা প্রতিটি অক্ষর প্রয়োজন হিসাবে গণনা করতে চান, এটি করার জন্য একটি দ্রুত ইউনিক্স আদেশ আছে?


56
ডিএনএ স্ট্র্যান্ডে ঘাঁটি গণনা করছেন?
ইন্দ্রেক

12
আমি এই প্রশ্নটি পছন্দ করি, একই সমস্যা সমাধানের জন্য ব্যবহৃত বিভিন্ন উপায় এবং সরঞ্জাম।
যাত্রামন গীক

10
হেই, এটি সীমান্তের কোড-গল্ফ
আর্লজ

13
যদি somone জানালা PowerShell সংস্করণ আগ্রহী:[System.IO.File]::ReadAllText("C:\yourfile.txt").ToCharArray() | Group-Object $_ | Sort Count -Descending
Guillaume86

4
ঠিক আছে আমি মনে করি আমি খাঁটি PS উপায় খুঁজে পেয়েছি:Get-Content "C:\eula.3082.txt" | % { $_.ToCharArray() } | Group-Object | Sort Count -Descending
গিলাইউমূম

উত্তর:


136

আপনি যদি কিছু বাস্তব গতি চান:

echo 'int cache[256],x,y;char buf[4096],letters[]="tacgn-"; int main(){while((x=read(0,buf,sizeof buf))>0)for(y=0;y<x;y++)cache[(unsigned char)buf[y]]++;for(x=0;x<sizeof letters-1;x++)printf("%c: %d\n",letters[x],cache[letters[x]]);}' | gcc -w -xc -; ./a.out < file; rm a.out;

একটি অবিশ্বাস্যভাবে দ্রুত সিউডো ওয়ান-লাইনার।

একটি সহজ পরীক্ষা দেখায় যে আমার কোর আই 7 সিপিইউ 870 @ 2.93GHz এ এটি 600MB / s এর চেয়ে বেশি গণনা করেছে:

$ du -h bigdna 
1.1G    bigdna

time ./a.out < bigdna 
t: 178977308
a: 178958411
c: 178958823
g: 178947772
n: 178959673
-: 178939837

real    0m1.718s
user    0m1.539s
sys     0m0.171s

বাছাইয়ের সাথে জড়িত সমাধানগুলির বিপরীতে, এইটি ধ্রুবক (4 কে) মেমরিতে চলে which

এবং অবশ্যই কিছুটা কনুই গ্রীস দিয়ে আমরা 0.7 সেকেন্ডের শেভ করতে পারি:

echo 'int cache[256],x,buf[4096],*bp,*ep;char letters[]="tacgn-"; int main(){while((ep=buf+(read(0,buf,sizeof buf)/sizeof(int)))>buf)for(bp=buf;bp<ep;bp++){cache[(*bp)&0xff]++;cache[(*bp>>8)&0xff]++;cache[(*bp>>16)&0xff]++;cache[(*bp>>24)&0xff]++;}for(x=0;x<sizeof letters-1;x++)printf("%c: %d\n",letters[x],cache[letters[x]]);}' | gcc -O2 -xc -; ./a.out < file; rm a.out;

নেটগুলি কেবলমাত্র 1.1GB / s এর মধ্যে শেষ করছে:

real    0m0.943s
user    0m0.798s
sys     0m0.134s

তুলনার জন্য, আমি এই পৃষ্ঠার অন্যান্য সমাধানগুলির কয়েকটি পরীক্ষা করেছি যা দেখে মনে হয়েছিল যে একরকম গতির প্রতিশ্রুতি রয়েছে।

sed/ awkসমাধান বীর চেষ্টা করলেন, কিন্তু 30 সেকেন্ড পর মারা যান। এই জাতীয় সরল রেগেক্সের সাথে, আমি এটি সেডে একটি বাগ হওয়ার প্রত্যাশা করব (জিএনইউ সেড সংস্করণ ৪.২.১):

$ time sed 's/./&\n/g' bigdna | awk '!/^$/{a[$0]++}END{for (i in a)print i,a[i];}' 
sed: couldn't re-allocate memory

real    0m31.326s
user    0m21.696s
sys     0m2.111s

পার্ল পদ্ধতিটিও আশাব্যঞ্জক বলে মনে হয়েছিল, তবে আমি এটি 7 মিনিটের জন্য চালানোর পরে ছেড়ে দিয়েছি

time perl -e 'while (<>) {$c{$&}++ while /./g} print "$c{$_} $_\n" for keys %c' < bigdna 
^C

real    7m44.161s
user    4m53.941s
sys     2m35.593s

1
+1 একটি বুদ্ধিমান সমাধানের জন্য যখন এটি প্রচুর ডেটা হয়, এবং কেবলমাত্র কয়েক মুষ্টি বাইট by ফাইলগুলি যদিও ডিস্ক ক্যাশে রয়েছে, তাইনা?
ড্যানিয়েল বেক

2
ঝরঝরে বিষয় হ'ল এটির প্রক্রিয়াকরণে ও (এন) এবং স্মৃতিতে ও (1) এর জটিলতা রয়েছে। পাইপগুলির প্রসেসিংয়ে সাধারণত ও (এন লগ এন) থাকে এবং মেমরিতে ও (এন ^ 2) এবং ও (এন) থাকে।
মার্টিন ইউডিং

73
যদিও আপনি "কমান্ড লাইন" এর সংজ্ঞাটি কিছুটা প্রসারিত করছেন।
10:44

11
প্রশ্নের প্রয়োজনীয়তাগুলির এপিক বেন্ডিং -আমি অনুমোদিত; পি। superuser.com/a/486037/10165 <- কেউ benchmarks দৌড়ে, এবং এই হল দ্রুততম বিকল্প।
যাত্রামন গীক

2
+1 আমি সঠিক জায়গায় সি এর কিছু ভাল ব্যবহারের প্রশংসা করি।
জেফ ফেরল্যান্ড

119

grep -o foo.text -e A -e T -e C -e G -e N -e -|sort|uniq -c

ওয়ান লাইনার হিসাবে ট্রিকটি করবে Will যদিও একটু ব্যাখ্যা দরকার।

grep -o foo.text -e A -e T -e C -e G -e N -e -a এবং g অক্ষরের জন্য ফাইল foo.text গ্রেপ করে এবং -আপনি যে প্রতিটি অক্ষরের সন্ধান করতে চান তার জন্য অক্ষরকে গ্রেপ করে । এটি এটিকে একটি চরিত্রকে একটি লাইনও ছাপায়।

sortএটি ক্রম সাজান। এটি পরবর্তী সরঞ্জামের মঞ্চ নির্ধারণ করে

uniq -cযে কোনও লাইনের সদৃশ ঘটনাকে গণনা করে। এই ক্ষেত্রে, যেহেতু আমাদের অক্ষরগুলির একটি বাছাই করা তালিকা রয়েছে, আমরা প্রথম ধাপে অক্ষরগুলি যখন ছাড়লাম তখন একটি ঝরঝরে গণনা পাই

যদি foo.txt এ স্ট্রিং থাকে GATTACA-তবে আমি কমান্ডের এই সেট থেকে পেয়ে যাব

[geek@atremis ~]$ grep -o foo.text -e A -e T -e C -e G -e N -e -|sort|uniq -c
      1 -
      3 A
      1 C
      1 G
      2 T

8
রক্তাক্ত ইউনিক্স ম্যাজিক! : ডি
পিট্টো

27
যদি আপনার ফাইলগুলিতে কেবলমাত্র সিটি TAG- অক্ষর থাকে তবে রেজপ্লেক্স নিজেই অর্থহীন হয়ে যায়, তাই না? গ্রেপ -ও। | সাজানো | uniq -c সমানভাবে ভাল কাজ করবে, কিন্তু।
syvvululul

7
+1 আমি 25 বছর ধরে গ্রেপ ব্যবহার করে আসছি এবং সে সম্পর্কে জানতাম না -o
লার্শ

9
@ জার্নিম্যানজিইক: এটির সাথে সমস্যাটি হ'ল এটি প্রচুর ডেটা তৈরি করে যা এর পরে বাছাই করতে পাঠানো হয়। একটি প্রোগ্রাম প্রতিটি চরিত্র পার্স করা সস্তা হবে। ও (এন) এর পরিবর্তে ও (এন) মেমরির জটিলতার উত্তরের জন্য ডেভের উত্তর দেখুন।
মার্টিন ইয়েডিং

2
@ পিট্টো নেটিভ উইন্ডোজ বিল্ডস কোরিউটিলগুলি বহুলভাবে পাওয়া যায় - কেবল গুগল বা
সামসুচকে

46

@ জার্নিম্যানের উত্তরে অনুপ্রাণিত হয়ে এটি ব্যবহার করে দেখুন।

grep -o -E 'A|T|C|G|N|-' foo.txt | sort | uniq -c

কীটি গ্রেপের জন্য -o বিকল্প সম্পর্কে জানছে । এটি ম্যাচটি বিভক্ত করে তোলে, যাতে প্রতিটি আউটপুট লাইন মেলে এমন কোনও লাইনের পুরো লাইনটির চেয়ে প্যাটার্নের একক উদাহরণের সাথে মিলে যায়। এই জ্ঞান দেওয়া, আমাদের প্রয়োজন কেবল ব্যবহার করার একটি প্যাটার্ন এবং লাইনগুলি গণনা করার একটি উপায়। একটি রেজেক্স ব্যবহার করে, আমরা একটি বিচ্ছিন্ন প্যাটার্ন তৈরি করতে পারি যা আপনার উল্লেখ করা যে কোনও অক্ষরের সাথে মিলবে:

A|T|C|G|N|-

এর অর্থ "ম্যাচ এ বা টি বা সি বা জি বা এন বা -"। ম্যানুয়ালটিতে আপনি ব্যবহার করতে পারেন এমন বিভিন্ন নিয়মিত অভিব্যক্তি সিনট্যাক্স বর্ণনা করে ।

এখন আমাদের আউটপুট রয়েছে যা দেখতে এরকম কিছু দেখাচ্ছে:

$ grep -o -E 'A|T|C|G|N|-' foo.txt 
A
T
C
G
N
-
-
A
A
N
N
N

আমাদের শেষ পদক্ষেপটি হ'ল sort | uniq -c@ জার্নিম্যানের উত্তর অনুসারে সমস্ত অনুরূপ লাইনগুলিকে একত্রিত করা এবং গণনা করা । বাছাই আমাদের এভাবে আউটপুট দেয়:

$ grep -o -E 'A|T|C|G|N|-' foo.txt | sort
-
-
A
A
A
C
G
N
N
N
N
T

কোনটি যখন পাইপ করা হয় uniq -c, শেষ পর্যন্ত আমরা যা চাই তার সাথে সাদৃশ্যপূর্ণ:

$ grep -o -E 'A|T|C|G|N|-' foo.txt | sort | uniq -c
      2 -
      3 A
      1 C
      1 G
      4 N
      1 T

সংযোজন: আপনি যদি কোনও ফাইলে এ, সি, জি, এন, টি, এবং - অক্ষরের সংখ্যা মোট করতে চান তবে আপনি এর wc -lপরিবর্তে গ্রেপ আউটপুটটি পাইপ করতে পারেন sort | uniq -c। এই পদ্ধতির সামান্য পরিবর্তন দিয়ে আপনি গণনা করতে পারবেন এমন প্রচুর পরিমাণে আছে।


আমার সত্যই কোরবিটোলস এবং রেজেক্সের রাববিথোলগুলিতে প্রবেশ করা দরকার। এটি আমার চেয়ে কিছুটা মার্জিত এটির জন্য; পি
জার্নম্যান গেক

2
@ জার্নিম্যানজেক: সমস্যাটি অনেকটা কার্যকর, কারণ এটি অনেক কিছুর জন্য কার্যকর। এটির সীমাবদ্ধতাগুলি কেবল বুঝতে পারুন এবং এক্সএইচটিএমএল পার্স করার মতো রেজেক্সেস ক্যাব্যাবিলাইটের ক্ষেত্রের বাইরে কাজ করার চেষ্টা করে শক্তিকে অপব্যবহার করবেন না ।
পাগল

20
গ্রেপ-ও '[এটিসিজিএন-]' এখানে কিছুটা বেশি পঠনযোগ্য হতে পারে।
sylvainulg

14

পাইথন ব্যবহার করে একটি অক্ষর সমস্ত অক্ষর গণনা করছে:

$ python -c "import collections, pprint; pprint.pprint(dict(collections.Counter(open('FILENAME_HERE', 'r').read())))"

... এর মতো YAML বান্ধব আউটপুট উত্পাদন করা হচ্ছে:

{'\n': 202,
 ' ': 2153,
 '!': 4,
 '"': 62,
 '#': 12,
 '%': 9,
 "'": 10,
 '(': 84,
 ')': 84,
 '*': 1,
 ',': 39,
 '-': 5,
 '.': 121,
 '/': 12,
 '0': 5,
 '1': 7,
 '2': 1,
 '3': 1,
 ':': 65,
 ';': 3,
 '<': 1,
 '=': 41,
 '>': 12,
 '@': 6,
 'A': 3,
 'B': 2,
 'C': 1,
 'D': 3,
 'E': 25}

কোডটির স্বচ্ছতার ক্ষেত্রে পাইথন কীভাবে বেশিরভাগ সময় সহজেই এমনকি বাশকেও মারতে পারে তা দেখতে আকর্ষণীয়।


11

গুরুর awkপদ্ধতির মতো:

perl -e 'while (<>) {$c{$&}++ while /./g} print "$c{$_} $_\n" for keys %c'

10

কয়েক বছর ইউনিক্স ব্যবহার করার পরে, আপনি বিভিন্ন ফিল্টারিং এবং গণনা কার্য সম্পাদন করতে বেশ কয়েকটি ছোট ছোট অপারেশনকে একসাথে যুক্ত করতে খুব দক্ষ হন। সবাই তাদের নিজস্ব শৈলী কিছু মত awkএবং sed, কিছু মত cutএবং tr। আমি এটি করার উপায় এখানে:

একটি নির্দিষ্ট ফাইলের নাম প্রক্রিয়া করতে:

 od -a FILENAME_HERE | cut -b 9- | tr " " \\n | egrep -v "^$" | sort | uniq -c

বা ফিল্টার হিসাবে:

 od -a | cut -b 9- | tr " " \\n | egrep -v "^$" | sort | uniq -c

এটি এর মতো কাজ করে:

  1. od -a ফাইলকে ASCII অক্ষরগুলিতে পৃথক করে।
  2. cut -b 9-উপসর্গ odপুটগুলি মুছে ফেলে ।
  3. tr " " \\n অক্ষরের মধ্যে ফাঁকা স্থানগুলিকে নতুন লাইনে রূপান্তর করে যাতে প্রতি লাইনে একটি অক্ষর থাকে।
  4. egrep -v "^$" এটি তৈরি করে এমন অতিরিক্ত সমস্ত ফাঁকা রেখা থেকে মুক্তি পেয়ে যায়।
  5. sort প্রতিটি চরিত্রের উদাহরণ একত্রিত করে।
  6. uniq -c প্রতিটি লাইনের পুনরাবৃত্তির সংখ্যা গণনা করে।

আমি এটিকে খাওয়ালাম "হ্যালো, ওয়ার্ল্ড!" একটি নতুন লাইন অনুসরণ করে এবং এটি পেয়েছে:

  1 ,
  1 !
  1 d
  1 e
  1 H
  3 l
  1 nl
  2 o
  1 r
  1 sp
  1 w

9

sedঅংশ ভিত্তিক হওয়ার @ গুরুর উত্তর , এখানে ব্যবহার করে অন্য প্রবেশপথ uniq, ডেভিড শোয়ার্জ 'সমাধান অনুরূপ।

$ cat foo
aix
linux
bsd
foo
$ sed 's/\(.\)/\1\n/g' foo | sort | uniq -c
4 
1 a
1 b
1 d
1 f
2 i
1 l
1 n
2 o
1 s
1 u
2 x

1
ব্যবহার করুন [[:alpha:]]বদলে .মধ্যে sedশুধুমাত্র ম্যাচ অক্ষর এবং নতুন লাইন করতে।
ক্লডিয়াস

1
[[:alpha:]]আপনি যদি এমন -
স্টাফের

সঠিক। এটা প্রথম অন্য সব কিছুর ফিল্টার করার জন্য sed এবং তারপর স্পষ্টভাবে পছন্দসই অক্ষর উপর মেলে একটি দ্বিতীয় অভিব্যক্তি যোগ করার জন্য সুন্দর হতে পারে: sed -e 's/[^ATCGN-]//g' -e 's/\([ATCGN-]\)/\1\n/g' foo | sort | uniq -c। তবে, আমি কীভাবে সেখানে নতুনলাইনগুলি থেকে মুক্তি পাব জানি না: \
ক্লডিয়াস

7

আপনি একত্রিত করতে grepএবং এটি wcকরতে পারেন:

grep -o 'character' file.txt | wc -w

grepনির্দিষ্ট পাঠ্যের জন্য প্রদত্ত ফাইল (গুলি) অনুসন্ধান করে এবং -oঅপশনটি কেবলমাত্র প্রকৃত মিলগুলি (যেমন আপনি যে অক্ষরগুলির সন্ধান করছিলেন) মুদ্রণ করতে বলে, পরিবর্তে প্রতিটি পাঠ্য যেখানে অনুসন্ধান পাঠ্য ছিল তা মুদ্রণ করতে হবে পাওয়া.

wcপ্রতিটি ফাইলের জন্য বাইট, শব্দ এবং লাইন গণনা মুদ্রণ করে, বা এই ক্ষেত্রে grepকমান্ডের আউটপুট । -wবিকল্প বলা হয়েছে যে সব প্রতিটি শব্দ আপনার অনুসন্ধানের চরিত্র একজন সংঘটন হচ্ছে শব্দ গণনা। অবশ্যই, -lবিকল্পটি (যা লাইন গণনা করে) পাশাপাশি কাজ করবে, যেহেতু grepআপনার অনুসন্ধানের অক্ষরের প্রতিটি উপস্থিতি একটি পৃথক লাইনে মুদ্রণ করে।

একবারে বেশ কয়েকটি অক্ষরের জন্য এটি করতে, অক্ষরগুলিকে একটি অ্যারেতে রেখে তার উপরে লুপ করুন:

chars=(A T C G N -)
for c in "${chars[@]}"; do echo -n $c ' ' && grep -o $c file.txt | wc -w; done

উদাহরণ: স্ট্রিংযুক্ত ফাইলের জন্য TGC-GTCCNATGCGNNTCACANN-আউটপুটটি হবে:

A  3
T  4
C  6
G  4
N  5
-  2

আরও তথ্যের জন্য, দেখুন man grepএবং man wc


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


3
তারা চাইবে যে প্রতি চেকটারে এটি পুনরাবৃত্তি করা দরকার ... আমি যুক্ত করব। আমি শপথ করতে পারলাম আরও মার্জিত সমাধান আছে তবে এর জন্য আরও ঝুঁকির দরকার রয়েছে; পি
জার্নম্যান গিক

পছন্দ করুন একটি দৃষ্টিভঙ্গি যা মনে জাগে তা হ'ল অক্ষরগুলিকে একটি অ্যারেতে রেখে সেটির মধ্য দিয়ে লুপ করা। আমি আমার পোস্ট আপডেট করেছি।
ইন্দ্রেেক

খুব জটিল আইএমও কেবল গ্রেপ-বি-ইত্যাদি ব্যবহার করুন। আপনি যদি এটিটিকে একটি অ্যারেতে রাখেন এবং এটির মধ্য দিয়ে লুপ করেন তবে আপনার প্রতি চরিত্রের জন্য একবার গ্রেপ চক্রটি চালাতে হবে না?
যাত্রামন গীক

পছন্দ করেছেন uniq -cএছাড়াও সুন্দর বিন্যাসিত আউটপুট পাওয়ার আরও ভাল পদ্ধতির মতো মনে হয়। আমি কোন * নিক্স গুরু নই, উপরেরটি কেবল আমার সীমিত জ্ঞান এবং কিছু লোক পৃষ্ঠা থেকে একত্রিত করতে পেরেছি :)
ইন্দ্রেক

আমিও; পি, এবং আমার এক কাজ হিসাবে প্রায় শেষ 5000 টি অ্যাড্রেস বুক এন্ট্রি বাছাই করে জড়িত, এবং ইউনিক এটি অনেক সহজ করে তুলেছিল।
যাত্রামন গীক

7

22hgp10a.txt থেকে সিক্যুয়েন্স লাইনগুলি ব্যবহার করে আমার সিস্টেমে গ্রেপ এবং অ্যাডাব্লু এর মধ্যে সময় পার্থক্যটি অজানা উপায়টিকে ব্যবহার করে ...

[সম্পাদনা]: দ্যাভের সংকলিত সমাধানটি দেখার পরেও খুব ভয়াবহতা ভুলে যেতে পারেন, কারণ তিনি পুরো ফাইলের সংবেদনশীল গণনার জন্য এই ফাইলটিতে ~ 0.1 সেকেন্ডে শেষ করেছেন।

# A nice large sample file.
wget http://gutenberg.readingroo.ms/etext02/22hgp10a.txt

# Omit the regular text up to the start `>chr22` indicator.
sed -ie '1,/^>chr22/d' 22hgp10a.txt

sudo test # Just get sudo setup to not ask for password...

# ghostdog74 answered a question <linked below> about character frequency which
# gave me all case sensitive [ACGNTacgnt] counts in ~10 seconds.
sudo chrt -f 99 /usr/bin/time -f "%E elapsed, %c context switches" \
awk -vFS="" '{for(i=1;i<=NF;i++)w[$i]++}END{for(i in w) print i,w[i]}' 22hgp10a.txt

# The grep version given by Journeyman Geek took a whopping 3:41.47 minutes
# and yielded the case sensitive [ACGNT] counts.
sudo chrt -f 99 /usr/bin/time -f "%E elapsed, %c context switches" \
grep -o foo.text -e A -e T -e C -e G -e N -e -|sort|uniq -c

ঘোস্টডগের কেস সংবেদনশীল সংস্করণ ~ 14 সেকেন্ডে শেষ হয়েছে।

এই প্রশ্নের গৃহীত উত্তরে সেডটি ব্যাখ্যা করা হয়েছে ।
বেঞ্চমার্কিং এই প্রশ্নের গৃহীত উত্তরের মতো ।
ঘোস্টডোগ by৪ দ্বারা গৃহীত উত্তরটি এই প্রশ্নের উত্তর ছিল ।


1
আপনি s/cache[letters[x]]/cache[letters[x]]+cache[toupper(letters[x])]এটির গতিকে প্রভাবিত না করে এটিকে কে সংবেদনশীল করে তুলতে পারেন।
ডেভ

6

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

time cat /dev/random | tr -d -C 'AGCTN\-' | head -c16M >dna.txt
real    0m5.797s
user    0m6.816s
sys     0m1.371s

$ time tr -d -C 'AGCTN\-' <dna.txt | tee >(wc -c >tmp0.txt) | tr -d 'A' | 
tee >(wc -c >tmp1.txt) | tr -d 'G' | tee >(wc -c >tmp2.txt) | tr -d 'C' | 
tee >(wc -c >tmp3.txt) | tr -d 'T' | tee >(wc -c >tmp4.txt) | tr -d 'N' | 
tee >(wc -c >tmp5.txt) | tr -d '\-' | wc -c >tmp6.txt && cat tmp[0-6].txt

real    0m0.742s
user    0m0.883s
sys     0m0.866s

16777216
13983005
11184107
8387205
5591177
2795114
0

সংক্ষিপ্ত পরিমাণগুলি তখন tmp [0-6] .txt এ থাকে .. সুতরাং কাজ এখনও চলছে

এই পদ্ধতির মধ্যে কেবল 13 টি পাইপ রয়েছে, যা 1 এমবি কম স্মৃতিতে রূপান্তর করে।
অবশ্যই আমার প্রিয় সমাধানটি হ'ল:

time cat >f.c && gcc -O6 f.c && ./a.out
# then type your favourite c-program
real    0m42.130s

এটি একটি খুব সুন্দর ব্যবহার tr
অ্যাডাভিড

4

আমি সম্পর্কে uniqবা তার সম্পর্কে জানতাম না grep -o, তবে যেহেতু @ জার্নম্যানম্যান গেক এবং @ ক্রেজি 2 এর উপর আমার মন্তব্যগুলির এইরকম সমর্থন ছিল, সম্ভবত আমার এটিকে তার নিজের একটি নোঙরে পরিণত করা উচিত:

আপনি যদি জানেন যে আপনার ফাইলে কেবলমাত্র "ভাল" অক্ষর রয়েছে (যাদের আপনি গণনা করতে চান) তবে আপনি তার জন্য যেতে পারেন

grep . -o YourFile | sort | uniq -c

যদি কেবলমাত্র কয়েকটি অক্ষর গণনা করা উচিত এবং অন্যগুলি নাও (যেমন বিভাজক)

grep '[ACTGN-]' YourFile | sort | uniq -c

প্রথমটি নিয়মিত এক্সপ্রেশন ওয়াইল্ডকার্ড ব্যবহার করে ., যা কোনও একক অক্ষরের সাথে মেলে। দ্বিতীয়টি একটি 'স্বীকৃত অক্ষরগুলির সেট' ব্যবহার করে, কোনও নির্দিষ্ট ক্রম ছাড়াই, -শেষ হওয়া আবশ্যক ( A-C' Aএবং এর মধ্যে কোনও অক্ষর হিসাবে ব্যাখ্যা করা হয় C)। সেক্ষেত্রে উদ্ধৃতি আবশ্যক যাতে আপনার শেলটি প্রসারিত করার চেষ্টা না করে যাতে সিঙ্গল-ক্যারেক্টার ফাইলগুলি চেক করতে হয় (এবং কোনওটি না মিললে "কোনও মিল নেই" ত্রুটি তৈরি করে)।

নোট করুন যে "সাজান" এর একটি -uস্বতন্ত্র পতাকাও রয়েছে যাতে এটি কেবল একবার জিনিসগুলি প্রতিবেদন করে তবে ডুপ্লিকেটগুলি গণনা করার জন্য কোনও সহকর্মী পতাকা নেই, uniqএটি অবশ্যই বাধ্যতামূলক।


-আপনি যদি ব্যাকস্ল্যাশ দিয়ে এড়িয়ে যান তবে শেষের দরকার নেই: '[A\-CTGN]'ঠিক কাজ করা উচিত।
ইন্দ্রেেক

2

একটি নির্বোধ:

tr -cd ATCGN- | iconv -f ascii -t ucs2 | tr '\0' '\n' | sort | uniq -c
  • tr( -d) সমস্ত অক্ষর মুছে ফেলতে ( -c) এটিসিজিএন-
  • iconv প্রতি বাইট পরে 0 বাইট যুক্ত করতে ucs2 (UTF16 2 বাইটে সীমাবদ্ধ) রূপান্তর করতে,
  • অন্য trএকটি NL অক্ষর অনুবাদ করতে। এখন প্রতিটি চরিত্র নিজস্ব লাইনে রয়েছে
  • sort | uniq -cপ্রতিটি ইউনিট লাইন গণনা করতে

এটি অ-স্ট্যান্ডার্ড (জিএনইউ) -oগ্রেপ বিকল্পের বিকল্প


আপনি এখানে আদেশগুলি এবং যুক্তি সংক্ষিপ্ত বিবরণ দিতে পারেন?
অ্যান্ড্রু ল্যামবার্ট

2
time $( { tr -cd ACGTD- < dna.txt | dd | tr -d A | dd | tr -d C | dd | tr -d G |
dd | tr -d T | dd | tr -d D | dd | tr -d - | dd >/dev/null; } 2>tmp ) &&
grep byte < tmp | sort -r -g | awk '{ if ((s-$0)>=0) { print s-$0} s=$0 }'

আউটপুট ফর্ম্যাটটি সেরা নয় ...

real    0m0.176s
user    0m0.200s
sys     0m0.160s
2069046
2070218
2061086
2057418
2070062
2052266

কার্যপ্রণালীর তত্ত্ব:

  • $ ({আদেশ | কমান্ড} 2> টিএমপি) স্ট্রিমের স্টাডারকে একটি অস্থায়ী ফাইলে পুনঃনির্দেশ করে ।
  • stdout এ স্টিডিন আউটপুট দেয় এবং স্টাডারে পাস করা বাইটের সংখ্যা আউটপুট করে
  • tr -d একবারে একটি চরিত্র ফিল্টার করে out
  • গ্রেপ এবং বাছাই ডিডির আউটপুটটিকে উতরিত ক্রমে ফিল্টার করে
  • awk পার্থক্য গণনা করে
  • সাজানোর প্রক্রিয়াটি কেবল পোস্ট-প্রসেসিং পর্যায়ে ডিডির উদাহরণগুলির প্রস্থান আদেশের অনিশ্চয়তা পরিচালনা করতে ব্যবহৃত হয়

গতি 60MBps + বলে মনে হচ্ছে


উন্নতি: ট্যাম্প থেকে মুক্তি পাবেন? জড়িত চিঠি মুদ্রণের জন্য 'পেস্ট' ব্যবহার করবেন?
আকি সুহিকনেন

1

নমুনা ফাইল:

$ cat file
aix
unix
linux

COMMAND:

$ sed 's/./&\n/g' file | awk '!/^$/{a[$0]++}END{for (i in a)print i,a[i];}'
u 2
i 3
x 3
l 1
n 2
a 1

স্পষ্টতার অভাবের জন্য, এবং ব্যাখ্যা ছাড়াই ওয়ান-লাইনার পোস্ট করার জন্য 1 আফাইক, এটি একটি কাঁটাচামচ বোমা হতে পারে
পিপিসি

1

কয়েক জনকে একত্রিত করা

chars='abcdefghijklmnopqrstuvwxyz-'
grep -o -i "[$chars]" foo|sort | uniq -c

| sort -nrফ্রিকোয়েন্সি ক্রমে ফলাফল দেখতে যোগ করুন ।


1

সংক্ষিপ্ত উত্তর:

যদি পরিস্থিতি অনুমতি দেয় তবে অফসেট পেতে কেবলমাত্র অক্ষরের সাথে ফাইল ফাইলের আকারের তুলনা করুন এবং কেবল বাইটগুলি গণনা করুন।

আহ, তবে জটলা বিশদ:

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

এটি অনেকগুলি প্রতিবন্ধকতার মতো মনে হতে পারে তবে আপনি যদি সহজেই এগুলি স্থাপন করতে পারেন তবে আপনার যদি দেখার মতো একটি টন থাকে তবে এটি আমাকে সবচেয়ে সহজ / সেরা পারফরম্যান্স পদ্ধতির হিসাবে আঘাত করে (যা সম্ভবত ডিএনএ হয় বলে মনে হয়)। দৈর্ঘ্যের জন্য এক টন ফাইল পরীক্ষা করা এবং একটি ধ্রুবককে বিয়োগ করা প্রত্যেকের উপর গ্রেপ (বা অনুরূপ) চালানোর চেয়ে দ্রুত গাবস হবে।

এমন:

  • খাঁটি পাঠ্য ফাইলগুলিতে এগুলি সহজ অখণ্ড স্ট্রিং
  • এগুলি একই ভ্যানিলা অ-বিন্যাসকরণ পাঠ্য সম্পাদক হিসাবে স্কাইটের মতো তৈরি একই ধরণের ফাইল টাইপগুলিতে রয়েছে (যতক্ষণ আপনি স্পেস / রিটার্ন পরীক্ষা করে দেখবেন ততক্ষণ আটকানো ঠিক আছে) বা কেউ লিখেছেন এমন কোনও বেসিক প্রোগ্রাম basic

এবং দু'টি জিনিস যা মেটাতে পারে না তবে আমি প্রথম দিয়ে টেস্ট করব

  • ফাইলের নামগুলি সমান দৈর্ঘ্যের
  • ফাইলগুলি একই ডিরেক্টরিতে রয়েছে

নিম্নলিখিতটি করে অফসেট সন্ধানের চেষ্টা করুন:

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


1

হাসেল পথ:

import Data.Ord
import Data.List
import Control.Arrow

main :: IO ()
main = interact $
  show . sortBy (comparing fst) . map (length &&& head) . group . sort

এটি এর মতো কাজ করে:

112123123412345
=> sort
111112222333445
=> group
11111 2222 333 44 5
=> map (length &&& head)
(5 '1') (4 '2') (3 '3') (2 '4') (1,'5')
=> sortBy (comparing fst)
(1 '5') (2 '4') (3 '3') (4 '2') (5 '1')
=> one can add some pretty-printing here
...

সংকলন এবং ব্যবহার:

$ ghc -O2 q.hs
[1 of 1] Compiling Main             ( q.hs, q.o )
Linking q ...
$ echo 112123123412345 | ./q
[(1,'\n'),(1,'5'),(2,'4'),(3,'3'),(4,'2'),(5,'1')]%       
$ cat path/to/file | ./q
...

বিশাল ফাইলের জন্য ভাল না।


1

দ্রুত পার্ল হ্যাক:

perl -nle 'while(/[ATCGN]/g){$a{$&}+=1};END{for(keys(%a)){print "$_:$a{$_}"}}'
  • -n: ইনপুট লাইনগুলিতে Iterate কিন্তু তাদের জন্য কিছু মুদ্রণ করবেন না
  • -l: স্ট্রিপ বা অ্যাড লাইন স্বয়ংক্রিয়ভাবে বিরতি
  • while: বর্তমান লাইনে আপনার অনুরোধকৃত চিহ্নগুলির সমস্ত উপস্থিতিতে পুনরাবৃত্তি করুন
  • END: শেষে, মুদ্রণ ফলাফল
  • %a: হ্যাশ যেখানে মান সংরক্ষণ করা হয়

যে অক্ষরগুলি একেবারেই ঘটে না সেগুলি ফলাফলের অন্তর্ভুক্ত হবে না।

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