AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 571231
Accepted
will
will
Asked: 2020-03-05 22:37:22 +0800 CST2020-03-05 22:37:22 +0800 CST 2020-03-05 22:37:22 +0800 CST

如何在 bash 脚本文件中参数化我的命令?

  • 772

编辑——不使用 bash$1变量。示例使用字段指示符:$1, $2,$3是awk输入记录字段 不幸的是,我做这个例子太快了,把例子弄混了。

我相信这是一个普遍的问题。我awk用作演示工具。目的是将 ( awk) 脚本参数暗示到awk(或任何工具)命令中。

我们使用从 STDIN 到提供的字段awk来产生结果。标识符$1, $2,$3是awk来自 STDIN 流的字段。

所需的解决方案 A(首选概念),例如...

#!/bin/bash  -f
#   script: blue.sh
#
    awk -e '{ print $1 " and " $2 " silly example" ;}'
#

以及所需的输出:

$  echo  "red blue yellow" > ./blue.sh 
red and blue silly example
$

备选方案 B 可能被认为是:

#!/bin/bash  -f
#   script: green.sh
#
    wrk="awk -e '{ print \$3 \" and \" \$2 \" variable example\" ;}'  "
#
    echo "work is:"
    echo $wrk
    echo
    $wrk

以及所需的输出:

$  echo  "red blue yellow" > ./green.sh 
wrk is:
awk -e '{ print $3 " and " $2 " variable example" ;}'  

yellow and blue variable example
$

问题出在表达式的引用中-e。

有没有办法实现这两个例子?

bash quoting
  • 2 2 个回答
  • 180 Views

2 个回答

  • Voted
  1. Kusalananda
    2020-03-05T23:34:10+08:002020-03-05T23:34:10+08:00

    这可能是“我们如何运行存储在变量中的命令? ”的副本,但我会针对您的特定情况回答它,因为它有多个部分:

    1. 将命令存储在变量中并使用该变量运行它。
    2. 将数据传递到awk.

    “在变量中运行命令”位

    这是您的脚本的替代实现的建议:

    #!/bin/bash
    
    wrk=( awk -v a="$3" -v b="$2"
          'BEGIN { printf "%s and %s variable example\n", a, b }' )
    
    awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s silly example\n", a, b }'
    
    printf 'wrk is: %s\n' "${wrk[*]}"
    "${wrk[@]}"
    

    运行这个:

    $ ./blue.sh "red" "blue" "yellow"
    red and blue silly example
    wrk is: awk -v a=yellow -v b=blue BEGIN { printf "%s and %s variable example\n", a, b }
    yellow and blue variable example
    

    我所做的是将awk命令存储在数组而不是字符串中。这确保了可以正确引用数组的每个单独元素,同时仍然保持单独的元素,与数组的其他部分分开。例如,开头的单词是与数组中的最后一个条目(即整个代码awk)分开的一个单词。awk

    当"${wrk[@]}"用作命令时,数组的每个元素都用作单独的命令行参数(第一个元素是命令)。扩展的引用"${wrk[@]}"确保每个元素都被单独引用(使用${wrk[@]}不起作用)。

    这就是在变量中存储和运行命令的方式,即使用数组并确保正确引用数组元素和数组的扩展。

    对于printfshell 脚本中的调用,我使用"${wrk[*]}"从数组中生成单个字符串wrk(默认情况下所有元素用空格分隔)。您会注意到这不会保留对单个元素的任何引用,这是可以预料的,因为 shell 在创建数组时删除了这些元素(就像在执行类似的操作时删除了引号一样a='hello world')。

    要查看 的每个单独元素wrk,请改用类似的东西printf 'element: "%s"\n' "${wrk[@]}"。这将输出

    element: "awk"
    element: "-v"
    element: "a=yellow"
    element: "-v"
    element: "b=blue"
    element: "BEGIN { printf "%s and %s variable example\n", a, b }"
    

    在这种特殊情况下,根据您的需要,您还可以使用 shell 函数:

    #!/bin/bash
    
    wrk () {
        awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s variable example\n", a, b }'
    }
    
    
    awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s silly example\n", a, b }'
    
    wrk "$3" "$2"
    

    请注意,函数中的$1and$2指的是函数的第一个和第二个参数,而不是脚本的。

    运行这个:

    $ ./blue.sh "red" "blue" "yellow"
    red and blue silly example
    yellow and blue variable example
    

    -awk特定位

    要将数据传递给awk 我用来在命令行上-v 初始化awk变量。awk这比通过 shell 扩展将变量注入awk代码更可取,因为这样做可能会允许用户注入可执行代码而不仅仅是数据(例如,通过简单地$3包含 a;和一些awk代码)。有关更多信息,请参阅本网站上的“命令行参数 in awk ”和类似问题。

    您还可以将数据传递给awk使用环境变量:

    a=$3 b=$2 awk 'BEGIN { printf "%s and %s variable example\n", ENVIRON["a"], ENVIRON["b"] }' )
    

    或者,

    export a="$3"
    export b="$2"
    awk 'BEGIN { printf "%s and %s variable example\n", ENVIRON["a"], ENVIRON["b"] }' )
    

    我也在awk一个BEGIN块中执行代码,因为在标准输入上没有要读取的输入。

    • 4
  2. Best Answer
    will
    2020-03-18T19:16:53+08:002020-03-18T19:16:53+08:00

    我找到了一个解决方案,尽管结果与最初的设想完全不同。我无法找到一种方法来扩展bash命令中的 -script 变量,因此必须“构造”。事实证明,xargs由于几个原因,这与 shell 想要如何做它的事情有关。

    我将展示一个示例运行,然后是代码并描述如何/发生了什么。我用“# (2)”之类的标签标记了要讨论的区域。

    示例:

    输入...

    $ svn status -qu ..
    M            28637   /src/line.h
    M            28637   /src/line.cpp
            *    28637   /testing/CheckWindows.py
    

    加工...

    重复脚本有两个参数:

    1. 要在输入列表上执行的模板或一个或多个命令
    2. 过滤输入流的一些awk命令

    命令行:

     svn status -qu .. | repeat                                        \
                           'cp -v $ff  /mnt/testhost/testarea/r02/$ff' \
                           "{  if( $1 == "M" ){ print  $3; } }"
    

    输出...

    '/src/line.h' -> '/mnt/testhost/testarea/r02/src/line.h'
    '/src/line.cpp' -> '/mnt/testhost/testarea/r02/src/line.cpp'
    

    发生了什么?

    • 仅将本地修改的文件复制到r02/testarea
      • 显然过滤可以是任何东西
    • 的目的repeat是在输入的过滤列表上重复一组命令

    注释代码:

        #!/bin/bash
        #   repeat.bash
    
        function  repeat
        {
            local -a    actions=()
            local       DELIMITER=";"
            local       filter="${2}"
            local       cmd=""
    
            local       wrk="${1}${DELIMITER}"        # (1)   Template
            local       str=""
    
    
            while [[ $wrk  ]]                         # (2)   Split-up individual commands
            do
                str="${wrk%%"${DELIMITER}"*}"
                actions+=( "${str}" )
    
                wrk="${wrk#*"${DELIMITER}"}"
            done
    
            echo    "actions: "                       # (3)   Debugging code
    
            for action in "${actions[@]}"
            do
                echo  "        => \"${action}\"."
            done
            echo  "filter  => '${filter}'."
    
    
            ex="${filter}"                            # (4)   Awk instructions to 
                                                      #       process input stream
    
    
            for ff in $(awk -e "${ex}")               # (5)   .
            do
                for action in "${actions[@]}"         # (6)   .
                do
                    cmd="${action//\$\{ff\}/${ff}}"   # (7)   .
                    cmd="${cmd//\$ff/${ff}}"
    
                    ${cmd}                            # (8)   .
                done
            done
    
            return
    
        }
    
        repeat  "${@:1}"                              # (9)   .
    

    备注:

    1. Arg$1是命令模板。
      *
      在末尾添加一个额外的分隔符以供以后解析
    2. $1通常不止一个命令。将输入参数拆分为单独的分号分隔的命令字符串。
    3. 打印参数进行确认。
    4. 将过滤器加载到ex变量中。
      *
      在这个例子ex中只是过滤器作为$2.
    5. 循环从过滤的输入行生成的每个字符串。
      *
      ex成为awk要作为选择/生成过滤器执行的命令。
    6. 循环遍历所有action命令模板。
    7. 扩展$ff以及命令字符串中${ff}的语法。action
    8. 为每个文件执行每个生成的命令行:$ff.
    9. 调用函数来执行脚本。

    事实证明,这变得完全不同,因为无法直接将参数注入到awk或模板字符串中。然而,变通方法并不太方便,并展示了它是如何在没有神秘扩展等的情况下工作的。

    我相信这个想法很有用。现在我发现它非常方便,因为我有一个工作片段。

    • 0

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve