从命令行创建Shell脚本有困难

时间:2019-06-02 19:31:50

标签: regex shell perl command-line terminal

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

1 个答案:

答案 0 :(得分:4)

该代码段尝试生成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个字符,而且也经常使用包容性位置。