【问题标题】:Having difficulty creating a shell script from a command line从命令行创建 shell 脚本有困难
【发布时间】:2019-10-18 11:23:19
【问题描述】:

我在 perl 命令中使用变量时遇到了困难。

我正在尝试将 perl 命令转换为 bash 脚本。 bash 脚本将用于在任何给定文件中搜索给定的正则表达式模式。 bash 脚本应该首先请求打开哪个文件,然后请求正则表达式模式。

我已经有一个可用的命令行,但我尝试将其转换为 bash 脚本的所有操作都不起作用...我对命令行和 bash 脚本没有太多经验,我在互联网上阅读了很多似乎没有任何效果。

#!/bin/bash

read -p "Enter the path to the file : " file_path
read -p "Enter the regular expression : " reg_exp

perl -ln0777e 'my $count=1; print "===================== RESULTS ====================="; while (/'"${reg_exp}"'/g) {printf("[%02d] Offset: 0x%x length: %dB\n     Position: %d to %d \n     Hex match: %s\n     Original: %s\n", $count++, $-[ 0 ], length $1, $-[ 0 ], $-[ 0 ] + length( $1 ) - 1, unpack("H*",$1), $1)}' "${file_path}"

当我尝试在正则表达式中使用变量时,它似乎没有被解释为变量...

结果应该是这样的: enter image description here

我的命令行是这样的:

perl -ln0777e 'my $count=1; print "===================== RESULTS ====================="; while (/REGULAR_EXPRESSION/g) {printf("[%02d] Offset: 0x%x length: %dB\n     Position: %d to %d \n     Hex match: %s\n     Original: %s\n", $count++, $-[ 0 ], length $1, $-[ 0 ], $-[ 0 ] + length( $1 ) - 1, unpack("H*",$1), $1)}' SOURCE_FILE

解决方案:

这是我想出的工作代码。感谢池上的帮助!

#!/bin/bash
read -rp "Enter the path to the file : " file_path
read -rp "Enter the regular expression : " reg_exp

perl -sn0777e'
   while (/$reg_exp/g) {
      printf "[%1\$02d] Matched %2\$d bytes from position %3\$d (0x%3\$x) to %4\$d (0x%4\$x)\n",
         ++$count, $+[0]-$-[0], $-[0], $+[0]-1;
      printf "     Hex: %s\n", unpack("H*", $&);
      printf "     Match: %s\n", $&; 
   }
' -- -reg_exp="${reg_exp}" -- "${file_path}"

【问题讨论】:

    标签: regex shell perl command-line terminal


    【解决方案1】:

    sn-p 尝试生成 Perl 代码,但这样做不正确。这被称为code injection 错误。

    解决此问题的最简单方法是完全避免生成 Perl 代码。 This other answer 建议将数据传递给 Perl 单行器的方法。我们将在这里使用第二个。

    perl -sn0777e'
       while (/$reg_exp/g) {
          printf "[%1\$02d] Matched %2\$d bytes from position %3\$d (0x%3\$x) to %4\$d (0x%4\$x)\n",
             ++$count, $+[0]-$-[0], $-[0], $+[0]-1;
          printf "Match: %s\n", $&; 
          printf "Hex: %s\n", unpack("H*", $&);
       }
    ' -- -reg_exp="$reg_exp" -- "$file_path"
    

    我做了一些改动:

    • 我通过使用$&$+[0] 的组合而不是$1(和length($1)),消除了对模式嵌入到捕获中的(未经验证的)期望。
    • 我使输出更清晰、更一致。
    • 我使代码更具可读性。

    请注意,对于 0 字符匹配,您可能会得到奇怪的输出(例如 0 bytes from position 6 to 5)。出于这个原因,经常使用排他的结束位置($+[0] 而不是$+[0]-1)。我保持不变,因为 0 字符匹配不太可能,并且也经常使用包含位置。

    【讨论】:

    • 如果我直接插入值而不是变量,这段代码可以工作......但是使用变量时,它不会产生预期的结果。好像不能动态生成命令行一样。
    • 对,我解释了为什么会这样,我解释了如何修复它,我提供了修复它。 (我刚刚修复的输出有一个小问题。)
    • 好的...我找到了问题所在! :D 显然,使用“read -p”会吃掉反斜杠字符......我不得不使用“read -rp”来保留它们。
    • 现在您知道为什么在演示问题时提供输入也很重要。请注意,您仍然需要我提供的修复程序
    猜你喜欢
    • 2017-07-12
    • 2015-01-18
    • 1970-01-01
    • 2013-11-03
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多