首页 > 解决方案 > 从命令行创建 shell 脚本有困难

问题描述

我在 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}"

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

结果应该是这样的: 在此处输入图像描述

我的命令行是这样的:

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}"

标签: regexshellperlcommand-lineterminal

解决方案


该片段尝试生成 Perl 代码,但这样做不正确。这被称为代码注入错误。

解决此问题的最简单方法是完全避免生成 Perl 代码。这个另一个答案提出了将数据传递给 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"

我做了一些改变:

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

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


推荐阅读