grep 命令在 csh 中搜索文件中的确切单词时给出意外输出

grep command giving unexpected output when searching exact word in file in csh

我使用以下脚本在另一个文件中搜索一个文件的每一行,如果发现打印该行的第二列:

#!/bin/csh

set goldFile=
set regFile=

set noglob
foreach line ("`cat $goldFile`")
    set searchString=`echo $line | awk '{print }'`
    set id=`grep -w -F "$searchString" $regFile | awk '{print }'`
    echo "$searchString" "and" "$id"
end

unset noglob

黄金档案如下:

$#%$%escaped.Integer%^^&[10]
$#%$%escaped.Integer%^^&[10][0][0][31]
$#%$%escaped.Integer%^^&[10][0][0][30]
$#%$%escaped.Integer%^^&[10][0][0][29]
$#%$%escaped.Integer%^^&[10][0][0][28]
$#%$%escaped.Integer%^^&[10][0][0][27]
$#%$%escaped.Integer%^^&[10][0][0][26]

RegFile如下:

$#%$%escaped.Integer%^^&[10] 1
$#%$%escaped.Integer%^^&[10][0][0][31] 10
$#%$%escaped.Integer%^^&[10][0][0][30] 11
$#%$%escaped.Integer%^^&[10][0][0][29] 12
$#%$%escaped.Integer%^^&[10][0][0][28] 13
$#%$%escaped.Integer%^^&[10][0][0][27] 14
$#%$%escaped.Integer%^^&[10][0][0][26] 15

即将输出:

$#%$%escaped.Integer%^^&[10] and 1 10 11 12 13 14 15
$#%$%escaped.Integer%^^&[10][0][0][31] and 10
$#%$%escaped.Integer%^^&[10][0][0][30] and 11
$#%$%escaped.Integer%^^&[10][0][0][29] and 12
$#%$%escaped.Integer%^^&[10][0][0][28] and 13
$#%$%escaped.Integer%^^&[10][0][0][27] and 14
$#%$%escaped.Integer%^^&[10][0][0][26] and 15

但预期输出是:

$#%$%escaped.Integer%^^&[10] and 1
$#%$%escaped.Integer%^^&[10][0][0][31] and 10
$#%$%escaped.Integer%^^&[10][0][0][30] and 11
$#%$%escaped.Integer%^^&[10][0][0][29] and 12
$#%$%escaped.Integer%^^&[10][0][0][28] and 13
$#%$%escaped.Integer%^^&[10][0][0][27] and 14
$#%$%escaped.Integer%^^&[10][0][0][26] and 15

请帮我弄清楚如何使用 grep 搜索具有某些特殊字符的确切单词。

csh and bash are completely different variants of shell. They're not even supposed to be compatible. Your problem is more associated with usage of grep

由于 grep 中的 -F 标志让您的字符串成为固定模式,容易包含各种正则表达式特殊字符,如 ,[] ,(),.,*,^,$,-,\

错误结果是因为-F标志,Gold文件中的行$#%$%escaped.Integer%^^&[10]匹配了RegFile.

上的所有输入行

所以通常搜索的确切词可以通过词边界结构 ^$ 作为模式的一部分进行过滤,但它在你的情况下不起作用,因为 -F, --fixed-strings 标记它们将被视为搜索字符串的一部分。

So assuming from the input file, there could be only one match for each line in the Gold file to RegFile you could stop the grep search after the first hit

使用 -m1 标志,根据 man grep 页面所述,

-m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  If the input is standard input 
          from a regular file, and NUM matching lines are output, grep ensures that the 
          standard input  is  positioned  to just  after  the  last  matching  line  before  
          exiting,  regardless of the presence of trailing context lines.  

所以添加它,

grep -w -F -m1 "$searchString" $regFile

应该可以解决你的问题。