如何将包含换行符的字符串文字从bash脚本传递给grep

时间:2017-05-23 22:32:37

标签: bash grep

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

从手册页的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' [...]

1 个答案:

答案 0 :(得分:0)

尝试以下方法:

#!/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>0' "$inFile")"

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

  • 除非您想传递文字 \"字符,否则请勿使用"。到目标命令 - 而不是带有语法含义 shell 的未加引号的命令。

    • 在您的特定情况下,\"$STRINGS\"细分如下:
      • 对变量$STRINGS未加引号引用 - 因为封闭的"\ - 已转义,因此文字
      • 结果字符串 - "<value-of-$STRINGS>" - 由于$STRINGS 未加引号,然后受word-splitting的约束 (和globbing),即按空格分成多个参数。因此,由于grep期望搜索字词为单个参数,因此命令会中断。
  • 不要使用全大写的shell变量名来avoid conflicts with environment variables and special shell variables