zoukankan      html  css  js  c++  java
  • awk,perl,python的命令行参数处理

    Python,Perl,Bash命令行参数 Part I

    日常经常性的和Perl,Python,Bash打交道,但是又经常性的搞混他们之间,在命令行上的特殊性和index的区别,Python真的是人性化到家了,但是命令行上就很原始,但是很有分类感。还是会喜欢Perl一点(至少还可以动脑子,不至于生锈),感觉Perl是个杂合子,而python像胡彦斌,bash像韩红(最近看我是歌手第三季,嘻嘻)。Bash就是家常菜了,虽然Perl可以大部分代替Bash的功能,像grep sort map等,但是某些时候真心很麻烦,还是直接在命令行中bash好一些和命令感觉好。[如不苟同,忍气吞声就好]

    下面将是我很多一部分的其中一小部分的开始,由于不断的装系统,更换系统过程中造成了很多总结的丢失,现在又要重新开始整理,很恼火,但是,回想旧爱也是甜蜜的。 


    基础篇


     

    Perl

    默认的命令行参数保存在@ARGV数组中

    获取用 $ARGV[0],$ARGV[1],… 来表示第1个,第2个参数,…

    $0表示当前脚本的文件名,和Bash一样

    注意:就即使你是perl script.pl A B C,$0也会是script.pl,而不会是perl

     

    Python

    是需要sys模块

    import sys

    sys.argv是一个list,列表(用sys.argv.__class__查看)

    获取用sys.argv[1],sys.argv[2],… 来表示第1个,第2个参数,…

    sys.argv[0]表示文件名

     

    Bash

    是直接用$n,$@,$*表示所有的参数[有区别,see below]

    获取用$1,$2,… 来表示第1个,第2个参数

    $0始终表示文件名,即使在函数中

    bash的每个函数也是这个规律的,$@表示所有

    $0,$1,$2分别表示第1个,第2个,第3个传递给函数的参数

    > cat test.sh

    1 #!/bin/bash
    2 function aa() {
    3     echo $0, $1,$2
    4 }
    5 aa I love you

    结果:test.sh,I,love


     提升篇


     

    很多时候,要共享脚本,要写清楚参数的顺序才可以,不然天知道该怎么传参数,如果看代码也不知道什么顺序。可以用注释注明顺序,或者写个usage()和简单的-h选项也可以,但谁能保证你的代码就可以被正常运行的,所以嘛,还是用getopts比较好,Linux/Unix有原生的getopt(s)命令的,Python和Perl也有相应的模块可以使用。

     

    Bash

    先看一个例子(getopts)

     

    > cat vallis.sh

     1 YON="don’t love"
     2 while getopts 'F:nO:t:' OPT; do
     3     case $OPT in
     4         F) Who=$OPTARG;;
     5         n) YON='love';;
     6         O) TGT=$OPTARG;;
     7         t) TL=$OPTARG;;
     8         ?) echo '-h for help';;
     9     esac
    10 done
    11 echo $Who $YON $TGT $TL
    12 shift $(($OPTIND - 1))
    13 echo $*

    sh untitled.sh -F I -O you -t baby -n forever

    结果是

    I love you baby

    forever

    解析一下就是

    先是一个while框架循环

    while …;do

    done

    再是 getopts 'F:nO:t:’ OPT 就是按optstring提取相应的值到$OPTARG中

    每次只提取一个,所以使用到while循环,当然可以使用for loop了

    optstring部分的'F:nO:t:’

    1. 每个字母代表一个短选项(short option),带冒号:的表示有选项值的,不带的表示没有值,相当于开关true/false
    2. 不在optstring中的会给出警告信息,可以在最前面加上:就可以了
    3. 2个很重要的参数是OPTARG和OPTINT(1-based),$OPTARG表示当前选项的值,$OPTINT表示在参数列表中的位移
    4. 选项(-)和选项值之间的空格是可有可无的(Mac OS X 10.10下成功)
    5. 不支持长选项(—)
    6. option部分必须写在其他参数之前,从OPTINT看出

    紧接着是case框架分选

    case $i in

    …) statement1

         statement2;; #注意每个(block)结束的时候要用;;分割

    esac

    shift $(($OPTIND - 1))是将argv中的剩下的不是opt部分(opt部分已经处理过了)的参数重新set为$1,$2,…

    $*,$@,这样剩下的参数可以用$n来访问,也就是说,删去了前面的option部分

    上面的结果中的forever就是这样的

    如果不用shift的话,$1仍然是-F,$2是I,... 

    总体上bash的这个和linux C语言的一样繁琐,只适合简单的选项设置

     Another

    还有一个getopt命令,是bash内置的(built-ins),上面的getopts是外置的(not built-ins)

    区别在于getopt的参数是有-的(leading dash)并且和set结合使用

    > cat valli.sh

     1 YON="don’t love"
     2 args=`getopt F:nO:t: $*`
     3 for i; do
     4     case $i in
     5         -F)
     6             shift # shift out -F then $1 is its value
     7             Who=$1
     8             shift;;
     9             # can be replaced by
    10             # Who=$2
    11             # shift 2;;
    12             # appliable to -O and -t or any option with a value
    13         -n)
    14             YON='love'
    15             shift;;
    16         -O)
    17             shift
    18             TGT=$1
    19             shift;;
    20         -t)
    21             shift
    22             TL=$1
    23             shift;;
    24     esac
    25 done
    26 echo $Who $YON $TGT $TL
    27 echo $*

    或者

    > cat valli2.sh

     1 YON="don’t love"
     2 args=`getopt F:nO:t: $*`
     3 set -- $args #  but I think useless [5]
     4 for i; do
     5     case "$i" in
     6         -F)
     7             Who=$2
     8             shift 2;;
     9         -n)
    10             YON='love'
    11             shift;;
    12         -O)
    13             TGT=$2
    14             shift 2;;
    15         -t)
    16             TL=$2
    17             shift 2;;
    18         --)
    19             shift
    20             break;;
    21     esac
    22 done
    23 echo $Who $YON $TGT $TL
    24 echo $*

    同样成功

    好原始,真的就和linux C语言没什么区别

    注意

    1. getopt在Mac OS X 10.10反正不支持—long -n -o 等getopt参数[4],具体可以看reference:4
    2. getopt是内置的命令,getopts只能在shell script中

     

    Perl

    perl的getopt是常用的Getopt::Long,Getopt::Std模块,这个就比较智能了,排除不兼容[6]

    先看一下例子

     1 use Getopt::Std;
     2  
     3 %options=();
     4 getopts("F:O:nt:", \%options); #high spot
     5 $does="don't love";
     6 print "$options{F} " if defined $options{F};
     7 if (defined $options{n}){
     8     $does='love';
     9     print "$does ";
    10 }
    11 print "$options{O} " if defined $options{O};
    12 print "$options{t}
    " if defined $options{t};
    13 print "@ARGV
    ”;

    就像写英语作文一样顺畅自如,仿佛在交流。但是着实是个话痨。

    开始的%options哈希表的key为option,value为option value

     

    Python

    就是optaprse以及更新版argparse,但是更习惯用optparse,尽管2.7版之后不再开发。

    我有一篇论述:

     

    Reference:

    1.http://blog.csdn.net/t0nsha/article/details/8180553

    2.http://blog.csdn.net/zynong/article/details/6306486

    3.https://docs.python.org/3/library/getopt.html?highlight=getopt#module-getopt

    4.http://blog.csdn.net/breeze_life/article/details/9998645

    5.http://blog.163.com/code4fun@126/blog/static/45776537201012311432182/

    6.http://www.cnblogs.com/zjking99/articles/2117258.html

    7.http://alvinalexander.com/perl/perl-getopts-command-line-options-flags-in-perl

    如果你对某处或者某段错误忍无可忍或者急切希望改进,可以评论,微博私信,或者email给我antisunny@qq.com

    天和地是灰色的,砖和瓦也是灰色的。临街的墙几经风化,几经修补,刷过黑灰、白灰,涂过红漆,书写过不同内容的标语,又终于被覆盖;风雨再把覆盖层胡乱地揭下来,形成一片斑驳的杂色,融汇于灰色的笼罩之中。路旁的树木苍黑,瓦楞中芳草青青。 远处,炊烟缭绕。迷蒙的曙色中,矗立着...
  • 相关阅读:
    22 组合电路中的竞争--冒险
    21 典型的组合电路模块(2)
    vhdl和verilog的区别
    17 TTL电路系列(2)
    树莓派Pico
    ESP8266/ESP32自动下载电路原理分析
    CH340芯片
    26. 删除排序数组中的重复项
    25. K 个一组翻转链表
    23. 合并K个排序链表
  • 原文地址:https://www.cnblogs.com/raybiolee/p/4228209.html
Copyright © 2011-2022 走看看