क्या यह Gedit या कमांड लाइन के साथ पाठ फ़ाइल की हर चौथी पंक्ति को संशोधित करने के लिए संभव है?


11

मैं एक टेक्स्ट फ़ाइल को एक अलग टैब स्प्रेडशीट में बदलने की कोशिश कर रहा हूं। मेरी पाठ फ़ाइल कुछ इस प्रकार है:

Dog
Cat
Fish
Lizard
Wolf
Lion
Shark
Gecko
Coyote
Puma
Eel
Iguana

मानक खोज और Gedit या LibreOffice में कार्यों को बदलने के साथ, यह टैब के साथ पंक्ति के अंत को प्रतिस्थापित करना आसान है। लेकिन अगर मैं सिर्फ टैब्स के लिए गाड़ी की वापसी करता हूं, तो मुझे यह मिलेगा:

Dog   Cat   Fish   Lizard   Wolf   Lion   Shark   Gecko   Coyote   Puma   Eel   Iguana

लेकिन मुझे ऐसा करने की आवश्यकता है जो इस तरह दिखती है:

Dog   Cat   Fish   Lizard
Wolf   Lion   Shark   Gecko  
Coyote   Puma   Eel   Iguana

तो, क्या मैं हर चौथी पंक्ति को छोड़कर टैब के लिए पंक्ति वर्ण के प्रत्येक छोर को स्वैप कर सकता हूं ?

मुझे नहीं पता कि गेडिट या लिबरऑफिस जैसे प्रोग्राम के अंदर नियमित अभिव्यक्ति के साथ उस तरह की सशर्त पुनरावृत्ति हो सकती है, इसलिए शायद यह किसी प्रकार का कमांड लाइन फ़ंक्शन होना चाहिए? मुझे इस पर भी स्पष्ट नहीं है कि सबसे अच्छा उपकरण किसके साथ शुरू होता है।


अपडेट करें:

मैंने निम्नलिखित आदेशों की कोशिश की:

sed 'N;N;N;s/\n/\t/g' file > file.tsv

paste - - - - < file > file.tsv

pr -aT -s$'\t' -4 file > file.tsv

xargs -d '\n' -n4 < inputfile.txt

लेकिन जब मैं परिणामी tsvफ़ाइल को लिबर ऑफिस में खोलने की कोशिश करता हूं , तो कॉलम काफी सही नहीं होते हैं। मुझे यकीन नहीं है कि इसका मतलब है कि मैं उपरोक्त आदेशों को सही ढंग से निष्पादित नहीं कर रहा हूं, या अगर मैं लिब्रे ऑफिस आयात समारोह में कुछ गलत कर रहा हूं:

Calc में TSV ओपनिंग

संदर्भ के लिए, वांछित परिणाम इस तरह दिखना चाहिए:

उचित कॉलम

जवाबों:


16

आप कमांड-लाइन एडिटर का उपयोग कर सकते हैं जैसे किsed

sed 'N;N;N;s/\n/\t/g' file > file.tsv

या, अधिक प्रोग्रामिक रूप से, आप जिन लाइनों को GNU सेड के एड्रेस ऑपरेटर का उपयोग करना चाहते हैं, उनमें से प्रत्येक में बैकस्लैश लाइन कंटिन्यूएशन वर्णों को जोड़कर और निरंतर लाइनों को जोड़ने n skip mके लिए क्लासिक वन-लाइनर के साथ इसका अनुसरण करना चाहते हैं:

sed '0~4! s/$/\t\\/' file | sed -e :a -e '/\\$/N; s/\\\n//; ta'

उदाहरण के लिए सेड वन-लाइनर्स को देखें :

  1. यदि यह बैकस्लैश "\" के साथ समाप्त होता है, तो अगली पंक्ति में जोड़ें।

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

हालाँकि, IMHO itwould अन्य मानक टेक्स्ट-प्रोसेसिंग उपयोगिताओं में से एक के साथ आसान हो सकता है

paste - - - - < file > file.tsv

( -कॉलम की संख्या के अनुरूप होगा) या

pr -aT -s$'\t' -4 file > file.tsv

( -s$'\tयदि आप आउटपुट को कई टैब द्वारा अलग किए जाने का बुरा नहीं मानते हैं तो आप इसे छोड़ सकते हैं )।


अजीब री-इम्पोर्ट व्यवहार जो आप देख रहे हैं वह लगभग निश्चित रूप से है क्योंकि मूल फ़ाइल में विंडोज-स्टाइल सीआरएलएफ लाइन एंडिंग्स हैं। यदि आपको विंडोज से फाइलों के साथ काम करने की आवश्यकता है, तो आप विभिन्न तरीकों से कमांड में रूपांतरण को रोल कर सकते हैं

tr -d '\r' < file.csv | paste - - - -

या

sed 'N;N;N;s/\r\n/\t/g' file.csv

पूर्व सभी कैरिज रिटर्न को हटा देगा जबकि बाद में प्रत्येक नई लाइनों के अंत में एक सीआर को संरक्षित किया जाएगा (जो कि यदि आप चाहते हैं कि विंडोज पर इच्छित उपयोगकर्ता हो तो) क्या हो सकता है।


1
विंडोज-स्टाइल लाइन एंडिंग्स के बारे में एक नोट: उनके और यूनिक्स-शैली के बीच कनवर्ट करने के लिए मानक उपकरण हैं dos2unixऔर unix2dos
डेविड फोस्टरस्टर

13

आप xargsहमेशा एक ही स्थान के साथ अलग-अलग चार लाइनों को एक में विभाजित करने के लिए उपयोग कर सकते हैं :

xargs -d '\n' -n4 < inputfile.txt

-d '\n'एक नई रेखा वर्ण में इनपुट सीमांकक सेट करता है, अन्यथा यह रिक्त स्थान पर भी टूट जाएगा। यदि आपके पास प्रति इनपुट लाइन में केवल एक शब्द है, तो आप इसे छोड़ भी सकते हैं।
-n4तर्क संख्या (आउटपुट लाइन प्रति इनपुट आइटम की संख्या) को 4 पर सेट करता है।

आउटपुट:

Dog Cat Fish Lizard
Wolf Lion Shark Gecko
Coyote Puma Eel Iguana

या यदि आप एक स्थान के बजाय विभाजक के रूप में टैब चाहते हैं, तो आप उन्हें बाद में बदल सकते हैं। हालाँकि, यदि आपके पास अपनी इनपुट लाइनों में स्थान हैं, तो उन्हें भी बदल दिया जाएगा:

xargs -d '\n' -n4 | tr ' ' '\t'

आउटपुट (ब्राउज़र / टर्मिनल की टैब चौड़ाई पर निर्भर करता है):

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana

इस पद्धति का यह लाभ है कि यह तब भी यथोचित व्यवहार करती है, जब इनपुट की कुल पंक्तियों की संख्या चार से अधिक न हो।
एलियाह कगन

3

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

awk -v ORS="" '{print $1; print NR%4==0?"\n":"\t"}' file > file.tsv 

दो awk निर्मित चर हैं:

  • ORS: हे utput आर ecord एस eparator (डिफ़ॉल्ट = newline)। इसे प्रत्येक प्रिंट कमांड के अंत में जोड़ा जाता है।
  • NR: वर्तमान आर उल्लू एन के एन umber प्रसंस्करण है।

यह कमांड प्रत्येक पंक्ति के लिए, पहले (और यहां केवल) कॉलम की सामग्री प्रदर्शित करेगा। फिर यह NR4 के विभाजन के शेष भाग का परीक्षण करके एक नई रेखा या एक टैब जोड़ना चाहता है ।


3

एक और सबसे छोटा awkतरीका:

awk '{printf $0 (NR%4?"\t":"\n")}' infile

यह printf केवल एक स्तंभ अगले और अगले और ... और एक टैब के बाद \tचरित्र प्रत्येक के बाद, लेकिन जाएगा printf एक \newline चरित्र जब एन की भूरा रंग आर ecord का कारक था 4 (जहां NR%4वापस आ जाएगी 0 ) (झूठी जो क्या त्रिगुट ऑपरेटर है condition(s)?when-true:when-falseकर रहा है।)


3

इसका मेरा समाधान संयोजन sedऔर का उपयोग करना होगा sed। सबसे पहले, आप कुछ विशेष वर्ण के साथ हर चौथी पंक्ति को चिह्नित कर सकते हैं, उदाहरण के लिए >, इस समाधान का उपयोग करते हुए:

इस मामले में आप पंक्ति 5 से शुरू करना चाहते हैं और इसके बाद हर 4 वीं पंक्ति को चिह्नित करते हैं। जीएनयू में sedजिसे एक पते के रूप में दिया जा सकता है 5~4। आप इस कमांड का उपयोग कर सकते हैं:

sed '5~4s/^/>/' file1 > file2

फिर आपको नई कड़ियों को हटाने की जरूरत है, जो एक sedलूप के साथ की जा सकती हैं :

sed ':a;N;s/\n/ /;ba' file2 > file3

उदाहरण के लिए, उदाहरण के लिए, कुछ अन्य वर्णों में नई कथनों को परिवर्तित करने के आसान तरीके हैं tr:

tr '\n' ' ' < file2 > file3

किसी भी तरह से, दो का संयोजन देता है

Dog   Cat   Fish   Lizard   >Wolf   Lion   Shark   Gecko   >Coyote   Puma   Eel   Iguana

( sedसंस्करण एक अनुगामी न्यूलाइन छोड़ता है, जबकि trसंस्करण नहीं है)

उसके बाद, आपको केवल उन विशेष वर्णों को परिवर्तित करने की आवश्यकता है जिन्हें आपने नई सूचियों में डाला है; उदाहरण के लिए देखें newlines का उपयोग करने के लिए एक टैब-सीमांकित फ़ाइल कनवर्ट करें । इस मामले में, >नई स्थितियों में परिवर्तन करें:

sed 'y/>/\n/' file3 > outfile

yआदेश के रूप में ही कार्य tr, दूसरे में एक चरित्र बदलने, लेकिन आप उपयोग कर सकते हैं sसमान रूप से अच्छी तरह से यहाँ आदेश। इसके साथ s, आपको gलाइन में प्रत्येक मैच पर संचालित करना होगा ( sed 's/>/\n/g')।

दो मध्यवर्ती फाइलें बनाने के बजाय, आप पाइप का उपयोग कर सकते हैं:

$ sed '5~4s/^/>/' file | sed ':a;N;s/\n/ /;ba' | sed 'y/>/\n/'
Dog Cat Fish Lizard 
Wolf Lion Shark Gecko 
Coyote Puma Eel Iguana

यदि अनुगामी रिक्त स्थान एक समस्या है, तो आप उन्हें निकालने के लिए एक और कमांड जोड़ सकते हैं:

| sed 's/ $//'

2

"पूर्णता" के लिए यहाँ एक शुद्ध बैश समाधान है:

#!/usr/bin/env bash

sep=$'\t'

while read one \
      && read two \
      && read three \
      && read four
do
  printf "%s\n" "$one$sep$two$sep$three$sep$four"
done

रिक्त स्थान के साथ भी काम करता है, यह IFSठीक से निर्धारित है (जो कि डिफ़ॉल्ट रूप से, AFAIK द्वारा किया जाना चाहिए)। इसके अलावा, मुझे लगता है कि यह एक पोर्टेबल शेल स्क्रिप्ट भी हो सकती है और किसी भी POSIX संगत शेल के साथ काम कर सकती है।


1
यह सामान्य रूप से POSIX संगत गोले के लिए पोर्टेबल नहीं है, क्योंकि $' 'POSIX द्वारा उद्धरण के रूप की आवश्यकता नहीं है। उदाहरण के लिए, dash(जो shउबंटू पर डिफ़ॉल्ट रूप से प्रदान करता है), printf '%s\n' $'a\tb'बस आउटपुट चला रहा है $a\tb। हालांकि इसका मतलब यह नहीं है कि यह उपयोगी नहीं है; यह काम करता है। हालांकि, कुछ अन्य समाधानों के साथ जैसे लोगों ने पोस्ट किया है, यह अधूरा आउटपुट पैदा करता है यदि इनपुट की लाइनों की संख्या चार से अधिक नहीं है। इसके अलावा, मैं उपयोग करने की सलाह देता हूं read -r, क्योंकि यह सोचने का कोई कारण नहीं है कि इनपुट फ़ाइल में बैकस्लैश से बचने का विस्तार यहां वांछित है।
एलियाह कगन

आप बस कर सकते हैंprintf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$four"
terdon

2

एक विम मैक्रो (क्यू के साथ रिकॉर्ड किया गया) आपके ऑपरेशन को लागू कर सकता है, फिर तीन लाइनों को छोड़ दें। उसके बाद, आप बस उस मैक्रो n बार चलाते हैं।

उदाहरण के लिए:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q

2

चूँकि आपने Gedit समाधान मांगा था, इसलिए कुछ इस तरह काम करना चाहिए:

खोजें:

(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+

से बदलो:

\1\t\2\t\3\t\4\n

सुनिश्चित करें कि नियमित अभिव्यक्तियों के लिए चेकबॉक्स चिह्नित है।

यह काम किस प्रकार करता है:

पहला कदम \ _ + के साथ शब्द वर्णों की एक श्रृंखला को खोजने के लिए है, और अभिव्यक्ति के चारों ओर कोष्ठक लपेटकर चर \ 1 में परिणाम कैप्चर करें:

(\w+)

अगला हम पंक्ति समाप्त करने वाले पात्रों, \ r और \ n, या CR और LF की एक श्रृंखला की खोज करते हैं। चूंकि Windows स्वरूपित फ़ाइलें दोनों का उपयोग करती हैं, हम इन दोनों वर्णों को वर्गाकार कोष्ठकों में लपेटकर एक वर्ण वर्ग बनाते हैं। प्लस इसे एक या अधिक वर्णों की खोज करता है:

[\r\n]+

अंत में, हम इस 3 को अधिक बार दोहराते हैं, प्रत्येक बाद के शब्द को चर 2, \ 3, और \ 4 में संग्रहीत करते हैं। यह हमारी अभिव्यक्ति को सरल बनाता है। हमें बस टैब वर्ण, \ t, और एक नई पंक्ति वर्ण, \ n को आपके द्वारा आवश्यक स्वरूपण के लिए उपयुक्त स्थानों पर रखने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.