【问题标题】:How to pass string literal containing newlines to grep from bash script如何将包含换行符的字符串文字从bash脚本传递给grep
【发布时间】:2017-05-23 22:32:37
【问题描述】:

我正在尝试使用-F(固定字符串)参数将文件中的“字符串”作为输入传递给grep

来自grep 手册页,预期的格式是换行符分隔:

   -F, --fixed-strings
          Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be matched.

如何在 bash 中做到这一点?我有:

#!/bin/bash
INFILE=$1
DIR=$2

# Create a newline-separated string array
STRINGS="";
while read -r string; do
    STRINGS+=$'\n'$string;
done < <(strings $INFILE);

cd $DIR
for file in *; do
    grep -Frn \"$STRINGS\" .
done;

但 grep 会在运行时报告有关输入格式的错误。 Grep 将传递的字符串参数解释为参数——因此需要将它们作为一个大字符串文字传递。

使用 -x 调试 bash 并传递脚本本身给出的第一个参数 (INFILE):

+ grep -Frn '"' '#!/bin/bash' 'INFILE=$1' 'DIR=$2' [...]

【问题讨论】:

    标签: bash grep


    【解决方案1】:

    尝试以下方法:

    #!/bin/bash
    
    inFile=$1
    dir=$2
    
    # Read all lines output by `string` into a single variable using
    # a command substitution, $(...).
    # Note that the trailing newlines is trimmed, but grep still recognizes
    # the last line.
    strings="$(strings "$inFile")"
    
    cd "$dir"
    for file in *; do
      grep -Frn "$strings" .
    done
    
    • string 将在目标文件中找到的每个字符串输出到自己的行中,因此您可以通过命令替换 ($(...)) 原样使用其输出。

      • 附带说明:strings 用于从 二进制 文件中提取字符串,并且仅当字符串长度至少为 4 个 ASCII(!) 字符且为后跟换行符或 NUL。
        请注意,虽然POSIX spec for strings 确实要求在字符解释方面具有区域设置意识,但 GNU strings 和 BSD/macOS strings 都只能识别 7 位 ASCII 字符。

      • 相比之下,如果您的搜索字符串来自一个 text 文件,您希望从中去除空行和空白行,请使用 strings="$(awk 'NF&gt;0' "$inFile")"

    • 双引号引用您的变量引用和命令替换,以确保按原样使用它们的值。

    • 不要使用\",除非你想传递一个文字 " char。到目标命令 - 与对 shell 具有 句法含义 的未引用命令相反。

      • 在您的特定情况下,\"$STRINGS\" 分解如下:
        • 未引用对变量 $STRINGS 的引用 - 因为封闭的 "\ 转义,因此 文字
        • 生成的字符串 - "&lt;value-of-$STRINGS&gt;" - 由于 $STRINGS未引用,然后受制于 word-splitting (和通配符),即用空格分割成 多个 参数。因此,由于 grep 期望搜索词作为 单个 参数,因此命令中断。
    • 不要为了avoid conflicts with environment variables and special shell variables而使用全大写的shell变量名。

    【讨论】:

      猜你喜欢
      • 2012-12-02
      • 2016-09-15
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多