विषम संख्या वाली पंक्तियों को मुद्रित करें, समान संख्या वाली पंक्तियों को भी मुद्रित करें


18

मैं फ़ाइलों से विषम-क्रमांकित और समान-संख्या वाली पंक्तियों को मुद्रित करना चाहता हूं।

मुझे यह शेल स्क्रिप्ट मिली, जो गूंज का उपयोग करती है।

#!/bin/bash
# Write a shell script that, given a file name as the argument will write
# the even numbered line to a file with name evenfile and odd numbered lines
# in a text file called oddfile.
# -------------------------------------------------------------------------
# Copyright (c) 2001 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------

file=$1
counter=0

eout="evenfile.$$" # even file name
oout="oddfile.$$" # odd file name

if [ $# -eq 0 ]
then
    echo "$(basename $0) file"
    exit 1
fi

if [ ! -f $file ]
then
    echo "$file not a file"
    exit 2
fi

while read line
do
    # find out odd or even line number
    isEvenNo=$( expr $counter % 2 )

    if [ $isEvenNo -ne 0 ]
    then
        # even match
        echo $line >> $eout
    else
        # odd match
        echo $line >> $oout
    fi
    # increase counter by 1
    (( counter ++ ))
done < $file
echo "Even file - $eout"
echo "Odd file - $oout"

लेकिन वहाँ एक लाइन में यह करने के लिए एक रास्ता नहीं है?

हां, awk का उपयोग करें, मैं पढ़ता हूं।

सम-संख्या वाली पंक्तियाँ:

awk 'NR % 2' filename

विषम संख्या वाली रेखाएँ:

awk 'NR % 2 == 1' filename

लेकिन यह मेरे लिए काम नहीं करता है। दोनों समान के अनुसार, एक ही आउटपुट का उत्पादन करते हैं। जब मूल फ़ाइल की तुलना की जाती है, तो वे दोनों वास्तव में आधे लंबे होते हैं, और उन दोनों में विषम संख्या वाली रेखाएं होती हैं। क्या मुझसे कुछ ग़लत हो रहा है?


6
पहला एक होना चाहिए NR % 2 == 0, अन्यथा यह दूसरे के बराबर है।
enzotib

ऑनलाइन कई दस्तावेज़ (इस एक सहित) प्रतीत होते हैं कि एक खोज के शीर्ष पर दिखाई देता है जो बताता है कि NR% 2 आपको समान संख्याएँ देता है, जो कि सही नहीं है, यह आपको विषम देता है क्योंकि 1% 2 = 1 = सत्य, २% २ = ० = असत्य।

जवाबों:


12

जैसा कि आपने पूछा "एक पंक्ति में":

awk '{print>sprintf("%sfile.%d",NR%2?"odd":"even",PROCINFO["pid"])}' filename

ध्यान दें कि अधिकांश कोड आपके फैंसी आउटपुट फ़ाइल नाम विकल्प के कारण है। अन्यथा निम्नलिखित कोड "लाइन -1" और यहां तक ​​कि "लाइन -0" में भी अजीब लाइनें डालने के लिए पर्याप्त होगा।

awk '{print>"line-"NR%2}' filename

26

मैं जब भी संभव हो POSIX संगत होना पसंद करता हूं, इसलिए मैंने सोचा कि मैं इस वैकल्पिक विधि को पोस्ट करूंगा। मैं अक्सर xargsपाइपलाइनों से पहले, पाठ का उपयोग करने के लिए इनका उपयोग करता हूं ।

यहां तक ​​कि गिने लाइनों,

sed -n 'n;p'

मुद्रित विषम संख्याएँ,

sed -n 'p;n'

हालांकि मैं अक्सर उपयोग करता हूं awk, यह इस प्रकार के कार्य के लिए ओवरकिल है।


14

यह आसान है:

 sed -n 2~2p filename

फ़ाइल नाम से समान-संख्या वाली लाइनें प्रिंट करेगा

sed -n 1~2p filename

विषम-संख्या वाली पंक्तियों को मुद्रित करेगा।


1
+1, AWK का उपयोग न करने के लिए। POSIX sed नहीं, लेकिन यह अभी भी ठोस विधि है।
जेएम बेकर

@TechZilla मुझे समझ में नहीं आया "AWK का उपयोग" - awk POSIX भी है।
jw013

3
@ jw013: कुछ भी गलत नहीं है awk, व्यक्तिगत रूप से मैं इसे बहुत बार उपयोग करता हूं। मैंने कभी नहीं कहा था कि 'नॉट पॉसिक्स' के बारे में awk, मैं उत्तर के sedविकल्पों का उल्लेख कर रहा था । विशेष रूप से ~ऑपरेटर, यह एक GNU एक्सटेंशन है, जो अभी भी कई लोगों के लिए स्वीकार्य है। , I personally believe using इस साधारण कार्य के लिए 'AWK एक्सट्रॉनिकली awk` का उपयोग करने के संबंध में ओवरकिल है। तो +1 के साथ कार्य पूरा करने के लिए था sed, की तुलना में एक हल्का उपयोगिता awk
जेएम बेकर

1
किसी को समझा सकते हैं कि कैसे ~ ऑपरेटर यहाँ काम करता है?
फॉरवर्ड लर्नर

9

सम संख्याओं के लिए कोड होना चाहिए

awk 'NR%2==0' filename

और विषम संख्या के लिए

awk 'NR%2==1' filename

1
यह एक सही है। यहां तक ​​कि काम करता है अगर आपको 10 की वेतन वृद्धि में पंक्तियां प्राप्त करने की आवश्यकता है, तो कहें कि आपको आकार की एक फ़ाइल को 1million से 100k तक कम करने की आवश्यकता है। जैसा मुझे चाहिए था यह बिल्कुल वैसा ही है।
डेक्सटर

आप AWK में समान संख्या वाले कॉलम कैसे प्रिंट कर सकते हैं? मैं यह काम नहीं कर सकता gawk 'FS=",";NF%2==0' file.csv
hhh

2

आप इसे एकल sedमंगलाचरण के साथ कर सकते हैं, फ़ाइल को दो बार पढ़ने की आवश्यकता नहीं है:

sed '$!n
w even
d' infile > odd

या, यदि आप एक पंक्ति में पसंद करते हैं:

sed -e '$!n' -e 'w even' -e d infile > odd

ध्यान दें कि ये अपेक्षित परिणाम नहीं देंगे यदि किसी फ़ाइल में केवल एक पंक्ति है ( पहले निष्पादित नहीं किया गया है तो लाइन wको evenइसके बजाय काट दिया जाएगा )। उससे बचने के लिए, एक शर्त जोड़ें:oddn

sed -e '$!n' -e '1!{w even' -e 'd}' infile > odd

यह काम किस प्रकार करता है ? खैर, यह तीन sedआदेशों का उपयोग करता है :
n- यदि अंतिम पंक्ति पर नहीं है तो पैटर्न स्पेस को प्रिंट करें stdout(जिसे फ़ाइल में रीडायरेक्ट किया गया है odd), इसे अगली पंक्ति से बदलें (इसलिए अब यह एक समान लाइन को प्रोसेस कर रहा है) और शेष कमांड को निष्पादित करना जारी रखें
w- संलग्न करें फाइल करने के लिए पैटर्न स्पेस even
d- करंट पैटर्न स्पेस को डिलीट करें और साइकिल को रीस्टार्ट करें - इसका साइड इफेक्ट यह है कि sedपैटर्न स्पेस को ऑटो-प्रिंट कभी नहीं करेगा क्योंकि यह स्क्रिप्ट के अंत तक कभी नहीं पहुंचता है

दूसरे शब्दों में, nकेवल अजीब तर्ज पर निष्पादित किया जाता है और wऔर dकेवल यहां तक कि तर्ज पर क्रियान्वित कर रहे हैं। sedजब तक मैंने कहा, कभी भी ऑटोप्रिंट नहीं होता है, इनपुट में एक ही लाइन होती है।


क्या आप यह बता सकते हैं कि यह कैसे काम करता है?
फॉरएवर लर्नर

आपकी मदद के लिए बहुत बहुत धन्यवाद don_crissti। ईमानदारी से इसकी सराहना करते हैं, साथ ही उत्थान किया।
फॉरएवर लर्नर

0

इसे इस्तेमाल करे:

awk '{if(NR%2){print $0 > "odd.file"}else{print $0 > "even.file"}}' filename

क्या आप रिकॉर्ड संख्याओं के आउटपुट के बारे में निश्चित हैं?
मैनटवर्क

इसके बारे में क्षमा करें, मैंने इसे पूरी लाइनों को आउटपुट करने के लिए संशोधित किया है।
१२:११ को

0

मुझे पसंद आएगा perlक्योंकि मुझे पसंद है perl:

perl -pe 'BEGIN{open($e,">even_lines");open($o,">odd_lines")} $. % 2 ?select $o:select $e;'

इस तथ्य का उपयोग करता है कि -pस्पष्ट रूप से प्रिंट करता है, यह दोहराने के लिए कि कैसे sedकाम करता है - और हम selectयह चुनने के लिए उपयोग करते हैं कि कौन सी फ़ाइल हैंडल को लिखा जाए।

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