update specific field in text file in specific line

后端 未结 2 627
礼貌的吻别
礼貌的吻别 2021-01-17 02:42

Below is a code that I\'m able to update the quantity of my book. But I cant seem to make it so that I can update my other things like book name, author, price etc. Heres th

相关标签:
2条回答
  • 2021-01-17 03:07

    What about sed?

    sed 's/\bLord of The Ring\b/Lord of The King/' file
    

    $ cat file
    Harry Potter - The Half Blood Prince:J.K Rowling:40.30:10:50
    The little Red Riding Hood:Dan Lin:40.80:20:10
    Harry Potter - The Phoniex:J.K Rowling:50.00:30:20
    Harry Potter - The Deathly Hollow:Dan Lin:55.00:33:790
    Little Prince:The Prince:15.00:188:9
    Lord of The Ring:Johnny Dept:56.80:100:38
    Three Little Pig:Andrew Lim:89.10:290:189
    All About Ubuntu:Ubuntu Team:76.00:55:133
    Catch Me If You Can:Mary Ann:23.60:6:2
    Happy Day:Mary Ann:12.99:197:101
    haha:gaga:1:10:1
    
    $ sed 's/\bLord of The Ring\b/Lord of The King/' file
    Harry Potter - The Half Blood Prince:J.K Rowling:40.30:10:50
    The little Red Riding Hood:Dan Lin:40.80:20:10
    Harry Potter - The Phoniex:J.K Rowling:50.00:30:20
    Harry Potter - The Deathly Hollow:Dan Lin:55.00:33:790
    Little Prince:The Prince:15.00:188:9
    Lord of The King:Johnny Dept:56.80:100:38
    Three Little Pig:Andrew Lim:89.10:290:189
    All About Ubuntu:Ubuntu Team:76.00:55:133
    Catch Me If You Can:Mary Ann:23.60:6:2
    Happy Day:Mary Ann:12.99:197:101
    haha:gaga:1:10:1
    

    Send the output with redirection > to a new file or use sed's -i option for in place editing.

    • redirection

      sed 's/\bLord of The Ring\b/Lord of The King/' file>newfile
      
    • in place etit with .bak file

      sed -i.bak 's/\bLord of The Ring\b/Lord of The King/' file
      
    0 讨论(0)
  • 2021-01-17 03:13

    Like user1146332, I also suggest to switch to a more powerful language. Here an example using perl. It uses module Getopt::Long to read arguments and loops through the file for a matching line.

    It seems to work but it's up to you to do a better checking of errors, for example, that both book and author variables are defined before using them in the regular expression.

    One more thing, I use split() with a colon to extract fields, I don't know how you handle a book with a colon in its name but in that case you will need an additional module to parse CSV, like Text::CSV or fight harder with a better split expression.

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use Getopt::Long;
    
    my ($book, $author, $newbook, $quantity);
    
    my $r = GetOptions(
            q|book=s| => \$book,
            q|author=s| => \$author,
            q|newbook=s| => \$newbook,
            q|quantity=i| => \$quantity,
    ) or die;
    
    open my $fh, '<', $ARGV[0] or die;
    
    while ( <$fh> ) { 
            chomp;
            my @f = split /:/;
            next if @f < 5;
            if ( $f[0] =~ m/(?i)\Q$book\E/ &&
                 $f[1] =~ m/(?i)\Q$author\E/ ) { 
                    $f[0] = defined $newbook ? $newbook : $f[0];
                    $f[3] = defined $quantity ? $quantity : $f[3];
                    printf qq|%s\n|, join q|:|, @f; 
                    next;
            }   
    
            printf qq|%s\n|, $_; 
    }
    

    An example with:

    perl script.pl --book="lord of the ring" --author=dep --newbook="Lord of the King" --quantity=99 infile
    

    Yields:

    Harry Potter - The Half Blood Prince:J.K Rowling:40.30:10:50
    The little Red Riding Hood:Dan Lin:40.80:20:10
    Harry Potter - The Phoniex:J.K Rowling:50.00:30:20
    Harry Potter - The Deathly Hollow:Dan Lin:55.00:33:790
    Little Prince:The Prince:15.00:188:9
    Lord of the King:Johnny Dept:56.80:99:38
    Three Little Pig:Andrew Lim:89.10:290:189
    All About Ubuntu:Ubuntu Team:76.00:55:133
    Catch Me If You Can:Mary Ann:23.60:6:2
    Happy Day:Mary Ann:12.99:197:101
    haha:gaga:1:10:1
    
    0 讨论(0)
提交回复
热议问题