2012-07-19 15 views
10

में हर दूसरी पंक्ति को कैसे संसाधित करें मैं किसी भी बदलाव के बिना अजीब रेखाएं (1,3,5,7 ..) मुद्रित करना चाहता हूं, लेकिन लाइनों (2,4,6,8) प्रक्रिया के साथ शुरू होने वाली पाइपलाइन के साथ ग्रेप। मैं सब कुछ नई फाइल में लिखना चाहता हूं (बिना किसी बदलाव के विषम रेखाएं और लाइनों के लिए नए मूल्य)।बैश

मैं जानता हूँ कि awk में हर दूसरे लाइन मुद्रित करने के लिए कैसे:

awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print; }' file.fasta 

हालांकि, यहां तक ​​लाइनों के लिए, मैं {print; } उपयोग करना चाहते हैं न, लेकिन मैं बजाय मेरी ग्रेप पाइप लाइन का उपयोग करना चाहते।

एक सलाह की सराहना की जाएगी। बहुत बहुत धन्यवाद।

+3

'== 1 {प्रिंट;}' अनावश्यक है, बस 'अजीब' एनआर% 2 'अजीब रेखाएं मुद्रित करेगा' – Kevin

+0

सहायता के लिए सभी को धन्यवाद! – Perlnika

उत्तर

8

आप एक ऐसा करने के लिए योजना बना रहे हैं वास्तव में पाइप awk अंदर से

awk 'NR % 2 {print} !(NR % 2) && /pattern/ {print}' file.fasta 

हालांकि, अगर आप chepner already pointer out के रूप में तो एक बहुत अधिक करते हैं, चाहते हैं, आप कर सकते हैं: सरल grep, आप दूर अतिरिक्त कदम के साथ जैसे कर सकते हैं और awk के भीतर ही छानने करते हैं, । उदाहरण के लिए:

awk 'NR % 2 {print} !(NR % 2) {print | "grep pattern | rev" }' file.fasta 

आदेश "pattern | rev" करने के लिए एक पाइप (ध्यान दें आसपास उद्धरण) को खोलता है और इसे करने के लिए प्रिंट उत्पादन पुनर्निर्देश है। ध्यान दें कि इस मामले में आउटपुट उतना ही नहीं हो सकता है जितना आप उम्मीद कर सकते हैं; आप पाइप किए गए कमांड के आउटपुट के बाद पहले आउटपुट होने वाली सभी विषम रेखाओं के साथ समाप्त हो जाएंगे (जो लाइनों का उपभोग भी करते हैं)।


(अपनी टिप्पणी के जवाब में) प्रत्येक भी लाइन में वर्ण की संख्या की गणना करने के लिए, कोशिश:

awk 'NR % 2 {print} !(NR % 2) {print length($0)}' file.fasta 
+0

धन्यवाद। मैं लाइनों में अक्षरों की संख्या गिनने वाला हूं। – Perlnika

+0

@Perlnika आप अजीब में 'लंबाई' कमांड का उपयोग कर वर्णों की संख्या प्राप्त कर सकते हैं। अद्यतन उत्तर देखें। –

+0

@ पर्नलिका, कुछ फास्टा फाइलों में '-' या' X' जैसे विषम वर्ण हो सकते हैं, लेकिन आपने शायद उत्तर दिया है कि ओपी क्या चाहता है। – Steve

6

आप पाइप कर सकते हैं सीधे awk अंदर से:

awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print | "grep -o [actgnACTGN] | wc -l"; }' file.fasta 

सावधान रहें, हालांकि, कि यह आपके इनपुट फ़ाइल के आदेश सुरक्षित नहीं करेगा।

(चयनित जवाब हाथ में कार्य के लिए बेहतर है, लेकिन मैं यहाँ एक बाहरी कमांड के लिए प्रिंट बयान पाइप का एक उदाहरण के रूप में इस उत्तर छोड़ देंगे।)

+0

धन्यवाद, मैंने इसे 'एनआर% 2 == 1 {प्रिंट; } एनआर% 2 == 0 {प्रिंट | grep -o [actgnACTGN] | wc -l} 'फ़ाइल।फास्टा (लाइन में अक्षरों की संख्या गिनने के लिए) लेकिन डब्ल्यूसी स्टेटिंग के साथ समस्या थी: awk: line 1: wc पर या उसके पास वाक्यविन्यास त्रुटि (ताकि मुझे लगता है कि समस्या मेरी पाइपलाइन में है :) – Perlnika

+0

आपका क्या मतलब है संरक्षण आदेश? – Perlnika

+0

@ पर्नलिका का मतलब है कि आप पाइप के आउटपुट के बाद पहले आउटपुट होने वाली सभी विषम रेखाओं के साथ समाप्त हो जाएंगे (जो सभी लाइनों का उपभोग करता है) –

1

के लिए अपने पाइप लाइन उत्पादन करने के लिए अपने AWK उत्पादन के साथ क्रम में दिखाई देते हैं, तो आप प्रत्येक पुनरावृत्ति पर पाइपलाइन को बंद करने की आवश्यकता है। यह, ज़ाहिर है, बहुत अक्षम है।

awk 'BEGIN{ cmd = "grep -io \047[actgn]\047 | wc -l" } NR % 2 { print } NR % 2 == 0 { print | cmd; close(cmd) }' file.fasta 

आप जाहिरा तौर पर अक्षर हैं जो निर्दिष्ट सूची में नहीं हैं गिनती करने के लिए नहीं करना चाहते हैं, तो length($0) काम नहीं करेगा। यह काम करेंगे और बहुत तेजी से पाइप लाइन विधि की तुलना में होना चाहिए:

awk 'NR % 2 { print } NR % 2 == 0 {n = split($0, a, /[^actgnACTGN]/); print length($0) - n + 1}' file.fasta 

यह अक्षरों का उपयोग लाइन विभाजित करके काम करता है आप करते सीमांकक के रूप में नहीं चाहते हैं और की लंबाई से सबस्ट्रिंग की गिनती को घटाकर रेखा और जोड़ना 1. संक्षेप में, यह परिणाम के रूप में वांछित पात्रों की संख्या को छोड़कर लाइन की लंबाई से अवांछित वर्णों की संख्या को घटा देता है।