bash - बाश में विशिष्ट वर्ण कैसे ढूंढें और प्रिंट करें




parsing awk (3)

मेरे पास फाइल है:

AA,A=14,B=356,C=845,D=4516
BB,A=65,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,F=225

मुझे कभी नहीं पता कि पंक्ति में अगर ए, बी, सी या डी वैल्यू गुम है। लेकिन मुझे इस फाइल को बदलने की आवश्यकता है:

AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225

इसलिए यदि किसी भी मान को छापने का मौका - चिह्न मेरी योजना में समान पार्स करने के लिए आसान पार्सिंग है मुझे एक्केक समाधान पसंद है किसी भी सलाह या सहायता के लिए धन्यवाद

मेरी पहली कोशिश थी:

awk '{gsub(/[,]/, "\t")}; BEGIN{ FS = OFS = "\t" } { for(i=1; i<=NF; i++) if($i ~ /^ *$/) $i = "-" }; {print $0}'

लेकिन फिर मैंने देखा, कि कुछ मान गायब हैं।

संपादित करें:

मेरे हेडर से मुझे पता है कि मूल्य ए, बी, सी, डी, ई, एफ है ...


पर्ल को बचाव में!

आपने निर्दिष्ट नहीं किया है कि हेडर जानकारी कैसे प्राप्त करें, इसलिए निम्न स्क्रिप्ट में, @ हेडर सरणी सीधे आबादी है।

%to_idx हैश उनके सूचकांक में स्तंभ नामों को मैप करता है (ए => 0, बी => 1 आदि)।

प्रत्येक पंक्तियों को खेतों में विभाजित किया जाता है, प्रत्येक फ़ील्ड को अपेक्षित एक ( $next ) से तुलना की जाती है और यदि आवश्यक हो तो डैश मुद्रित होते हैं लापता पिछड़े क्षेत्रों के लिए ऐसा ही होता है

#!/usr/bin/perl
use warnings;
use strict;

my @header = qw( A B C D E F );

my %to_idx = map +($header[$_] => $_), 0 .. $#header;

open my $IN, '<', shift or die $!;
while (<$IN>) {
    chomp;
    my @fields = split /,/;
    print shift @fields;
    my $next = 0;
    for my $field (@fields) {
        my ($name, $value) = split /=/, $field;
        print ',-' x ($to_idx{$name} - $next);
        print ",$name=$value";
        $next = $to_idx{$name} + 1;
    }
    print ',-' x (1 + $#header - $next);  # Missing trailing fields.
    print "\n"
}

TXR में समाधान

@(do
   (defstruct fill-missing nil
     strings
     (hash (hash :equal-based))

     (:postinit (self)
       (each ((s self.strings))
         (set [self.hash s] "-")))

     (:method add (self str val)
       (set [self.hash str] `@[email protected]`))

     (:method print (self stream)
       (put-string `@{(mapcar self.hash self.strings) ","}` stream))))
@(repeat)
@  (bind fm @(new fill-missing strings '#"A B C D E F"))
@{label},@(coll)@{sym /[^,=]+/}[email protected]{val /[^,]+/}@(do fm.(add sym val))@(end)
@  (do (put-line `@label,@fm`))
@(end)

चलाएँ:

$ txr missing.txr data
AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225

BEGIN {                                  
    PROCINFO["sorted_in"]="@ind_str_asc" # order for for(i in a)
    for(i=65;i<=90;i++)                  # create the whole alphabet to array a[]
        a[sprintf("%c", i)]              # you could read the header and use that as well
}
{
    split($0,b,",")                      # split record by ","
    printf "%s", b[1]                    # printf first element (AA, BB...)
    delete b[1]                          # get rid of it
    for(i in b) 
        b[substr(b[i],1,1)]=b[i]         # take the first letter to use as index (A=12)
    for(i in a)                          # go thru alphabet and printf from b[]
        printf "%s%s", OFS, (i in b?b[i]:"-"); print ""
}

awk -v OFS=\, -f parsing.awk tbparsed.txt
AA,A=14,B=356,C=845,D=4516,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
CC,A=88,B=54,C=549,-,-,F=225,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-

यह रिकॉर्ड में नहीं मिले प्रत्येक पत्र के लिए प्रिंट करता है। यदि डेटा के शीर्ष पर था, तो आप 2-डी सरणी b[NR] को split कर सकते हैं और for(i in a) के for(i in a) for(i in b[1]) ... printf ... b[NR][b[1][i]] ... और अगर आपको स्थिर पहले कॉलम की आवश्यकता नहीं है, तो पहले printf delete और delete







find