提示用户输入然后在相应字段中添加和减去

时间:2013-08-04 03:56:26

标签: perl bash

我希望从$cpySold中减去变量$a[3]并添加到$a[4]。我该怎么办?

目前我的输出如下:

Title:Alice in wonderland
Author:robert
No Of Copies Sold:*3*

Current Book Info:
Alice in wonderland, robert,$12.40,100,200

我如何进行以下这一行?在用户输入 3 副本后,假设100- 3 = 97,100 + 3 = 103。

  

新书信息:爱丽丝梦游仙境,罗伯特,12.40,97,203美元

function process_book_sold
{
    read -p "Title: " title
    read -p "Author: " author
    read -p "No Of Copies Sold : " cpySold 
    if [ -n "$title" -a -n "$author" ]; then
    perl -ne 'BEGIN{ $pattern = $ARGV[0]; shift;$pattern1 = $ARGV[0]; shift; $n=0 }
    @a=split /:/;
    if ($a[0] =~ m/$pattern/i and $a[1] =~ m/$pattern1/i) 
    {
         print "Current Book Info: \n";
         print "$a[0], $a[1],\$$a[2],$a[3],$a[4]\n";
    }
    END{ print "\n" }' "$title" "$author" /home/student/Downloads/BookDB.txt
    fi
}

1 个答案:

答案 0 :(得分:0)

我不喜欢代码中shell和Perl的混合,但这显然是出于教学原因所以我们必须忽略它。

process_book_sold()
{
    read -p "Title: " title
    read -p "Author: " author
    read -p "No Of Copies Sold : " cpySold 
    if [ -n "$title" -a -n "$author" ]; then
        perl -ne '
            BEGIN{ $title = shift; $author = shift; $sales = shift; }
            @a = split /:/;
            if ($a[0] =~ m/$title/i and $a[1] =~ m/$author/i) 
            {
                 print "Current Book Info:\n";
                 print "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
                 $a[3] -= $sales;
                 $a[4] += $sales;
                 print "New Book Info:\n";
                 print "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
            }
            END{ print "\n" }' "$title" "$author" "$cpySold" /home/student/Downloads/BookDB.txt
    fi
}

除了将pattern重命名为titlepattern1重命名为author之外,此代码还将shell变量$cpySold传递给Perl。它还使用一种更简单的方法来检索前三个参数(只是从shift中捕获值)。 split与之前相同。目前还不完全清楚数据文件中的格式是什么,因为打印格式使用逗号而不是冒号来分隔字段。


  

我只想让新书信息中的值替换BookDB.txt文件中的当前图书信息。

我不相信这对你有任何好处(除非你自己尝试,否则你不会学到太多东西),但是......

process_book_sold()
{
    title="$1"
    author="$2"
    cpySold="$3"
    if [ -n "$title" -a -n "$author" ]
    then
        perl -i -we '
            use strict;
            use English "-no_match_vars";
            my $title = shift;
            my $author = shift;
            my $sales = shift;
            while (<>)
            {
                chomp;
                my @a = split /:/;
                print STDERR "Debug: @a\n";
                if ($a[0] =~ m/$title/i and $a[1] =~ m/$author/i) 
                {
                    print STDERR "Current Book Info:\n";
                    print STDERR "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
                    $a[3] -= $sales;
                    $a[4] += $sales;
                    print STDERR "New Book Info:\n";
                    print STDERR "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
                    $OFS = ":";
                    $ORS = "\n";
                    print @a;
                }
            }
            ' "$title" "$author" "$cpySold" BookDB.txt # /home/student/Downloads/BookDB.txt
    fi
}

#   read -p "Title: " title
#   read -p "Author: " author
#   read -p "No Of Copies Sold : " cpySold 
process_book_sold "Alice in Wonderland" "Carroll" "3"

这并不会让我输入标题,作者或销售的份数。如果您愿意,可以恢复这些行,但如果它接受参数,则该函数可能更有用。 (将用户交互与对文件进行操作的代码分开通常很好。)我使用了正确的作者姓名(除非您想使用Dodgson作为使用化名Lewis Carroll的作者的真实姓名)。 Perl脚本使用-i选项覆盖输入文件。它使用English模块,因此可以设置$OFS$ORS。它将调试信息写入STDERR(否则,它将成为写入文件的信息的一部分)。

当文件被调用pbs2.sh时,脚本的示例运行如下:

$ cat BookDB.txt; bash pbs2.sh; cat BookDB.txt
Alice in Wonderland:Carroll:$12.40:74:226
Debug: Alice in Wonderland Carroll $12.40 74 226
Current Book Info:
Alice in Wonderland, Carroll, $12.40, 74, 226
New Book Info:
Alice in Wonderland, Carroll, $12.40, 71, 229
Alice in Wonderland:Carroll:$12.40:71:229
$

显然,这不是我第一次运行脚本,有时我使用3以外的值来销售副本。

使用显式文件管理,您可以编写:

process_book_sold()
{
    title="$1"
    author="$2"
    cpySold="$3"
    if [ -n "$title" -a -n "$author" ]; then
        perl -we '
            use strict;
            use English "-no_match_vars";
            my $title = shift;
            my $author = shift;
            my $sales = shift;
            my $file = shift;
            open my $fh, "+<", $file or die "Failed to open file $file for reading and writing";
            my $text;
            {
            local $/;
            $text = <$fh>;
            }
            chomp $text;
            my @a = split /:/, $text;
            print "Debug: @a\n";
            if ($a[0] =~ m/$title/i and $a[1] =~ m/$author/i) 
            {
                print "Current Book Info:\n";
                print "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
                $a[3] -= $sales;
                $a[4] += $sales;
                print "New Book Info:\n";
                print "$a[0], $a[1], $a[2], $a[3], $a[4]\n";
                seek $fh, 0, 0;
                truncate $fh, 0;
                $OFS = ":";
                $ORS = "\n";
                print $fh @a;
            }
            close $fh;
            ' "$title" "$author" "$cpySold" BookDB.txt # /home/student/Downloads/BookDB.txt
    fi
}

# read -p "Title: " title
# read -p "Author: " author
# read -p "No Of Copies Sold : " cpySold 

process_book_sold "Alice in Wonderland" "Carroll" "7"

示例运行:

$ cat BookDB.txt; bash pbs1.sh; cat BookDB.txt
Alice in Wonderland:Carroll:$12.40:50:250
Debug: Alice in Wonderland Carroll $12.40 50 250
Current Book Info:
Alice in Wonderland, Carroll, $12.40, 50, 250
New Book Info:
Alice in Wonderland, Carroll, $12.40, 43, 257
Alice in Wonderland:Carroll:$12.40:43:257
$