टैब सीमांकित फ़ाइल में मानों का एक स्तंभ जोड़ना


17

मैं एक फ़ाइल में मूल्यों का एक कॉलम कैसे जोड़ सकता हूं जिसमें कुछ निश्चित पंक्तियाँ हैं। मेरे पास इस तरह की एक इनपुट फ़ाइल है:

इनपुट फ़ाइल:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248

आउटपुट फाइल:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1

इस स्थिति में, मैं फ़ाइल में पंक्तियों की संख्या तक मानों का एक कॉलम जोड़ना चाहता हूं। यह मान "जैसे" फ़ाइल 1 "के अनुरूप है।

कारण यह है कि मेरे पास उन फ़ाइलों में से 100 हैं। मैं प्रत्येक फ़ाइल को खोलना नहीं चाहता और एक कॉलम चिपकाता हूं। इसके अलावा, किसी निर्देशिका में जाकर और मानों का एक स्तंभ जोड़कर, इसे स्वचालित करने का कोई तरीका है। मान फ़ाइल नाम से आता है, जिसे अंतिम / पहले कॉलम में फ़ाइल की प्रत्येक पंक्ति में जोड़ा जाना है।

जवाबों:


22

आप इस तरह से एक-लाइनर लूप का उपयोग कर सकते हैं:

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done

सूची में प्रत्येक फ़ाइल के लिए, यह sedप्रत्येक पंक्ति के अंत में एक टैब और फ़ाइल नाम को जोड़ने के लिए उपयोग करेगा ।

स्पष्टीकरण:

  • फ़ाइल को अधिलेखित करने के लिए एक प्रतिस्थापन के -iसाथ ध्वज का उपयोग करनाsed
  • के साथ एक प्रतिस्थापन प्रदर्शन करते हैं s/PATTERN/REPLACEMENT/। इस उदाहरण में PATTERN है $, लाइन का अंत है, और REPLACEMENT \t(= a TAB) है, और $fलूप वैरिएबल से फ़ाइल नाम है। s///ताकि खोल चर विस्तार कर सकते हैं आदेश डबल उद्धरण के भीतर है।

कोड काम करता है। क्या आप उद्धरण के भीतर सामग्री की व्याख्या कर सकते हैं?
रॉन

जिस तरह कॉलम के साथ काम करते समय "awk" का उपयोग किया जाता है, उसी तरह की स्थितियों के लिए भी 'sed' का उपयोग किया जाता है। मैं नौसिखिया 'awk' और 'sed' हूं।
रॉन

@ रॉन sedपैटर्न प्रतिस्थापन और इन-प्लेस को बचाने के लिए सबसे अधिक व्यावहारिक है। फ़ाइल को सहेजने की आपकी आवश्यकता के लिए यह अपेक्षाकृत सुविधाजनक विकल्प था। यदि आपको उसी फ़ाइल पर वापस लिखने की आवश्यकता नहीं है जिसे आप संसाधित कर रहे हैं, तो awkआमतौर पर साथ काम करना बहुत आसान होता है।
जानूस

व्यक्तिगत रूप से, मैं awkबहुत बार अक्सर इनपुट / आउटपुट फ़ील्ड विभाजकों द्वारा फंस जाता हूं , और इसलिए जब भी संभव हो, इसका उपयोग करने से बचने की कोशिश करता हूं , और sedअधिक आकर्षक बनाता हूं ।
user5359531

11

आओ जब तुम लोग उन शक्तिशाली साधनों की सलाह देते हो, जब pasteआज्ञा होती है!

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4

थोड़ी सी चालाकी से, आप pasteओपी के उद्देश्य के लिए उपयोग कर सकते हैं । हालाँकि, यह फ़ाइलों की जगह नहीं लेगा:

for f in file1 file2 file3; do 
    paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done

यह संबंधित फ़ाइल नाम को प्रत्येक फ़ाइल के अंतिम कॉलम के रूप में नई फ़ाइल में पेस्ट करेगा filename.new


धन्यवाद! pasteनिश्चित रूप से एक छिपा हुआ रत्न है।
neu242

10

आप उपयोग कर सकते हैं awk:

awk '{print $0, FILENAME}' file1 file2 file3 ...

चूंकि प्रत्येक फ़ाइल का अलग-अलग नाम है, इसलिए मुझे इसे 100 बार करना होगा। क्या एक बार करने का कोई तरीका है?
रॉन

नहीं, FILENAMEयह एक चर है awk, यह वर्तमान फ़ाइल नाम के लिए विस्तारित है जो awkप्रसंस्करण है। आप इसे केवल एक करें, सभी फ़ाइलों को फ़ीड करें awk
22

ठीक है, लेकिन आउटपुट को नई फ़ाइल में कैसे निर्देशित किया जाए, प्रत्येक फ़ाइल का? क्या प्रसंस्करण के दौरान प्रत्येक फ़ाइल को संग्रहीत करता है?
रॉन

यदि आपके पास GNU awk 4.1.0या बाद में है, तो आप -iinplace को edit करने के लिए उपयोग कर सकते हैं । अन्यथा, आपको awkouput को एक अस्थायी फ़ाइल पर पुनर्निर्देशित करना चाहिए , फिर grepप्रत्येक फ़ाइलों से लाइन निकालने के लिए उपयोग करें।
cuonglm

वैसे आप कर सकते हैंfor file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
Fedorqui
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.