grep "^$1"
有点工作,但我如何转义"$1"
grep 不会特别解释其中的任何字符?
或者,还有更好的方法?
编辑:
我不想搜索'^$1'
但要搜索动态插入的固定字符串,该字符串仅在位于行首时才匹配。这就是我所说的$1
.
Las*_*ssi 14
如果您只需要检查是否找到匹配项,请将所有输入行剪切为所需前缀 ( $1
)的长度,然后使用固定模式 grep:
if cut -c 1-"${#1}" | grep -qF "$1"; then
echo "found"
else
echo "not found"
fi
Run Code Online (Sandbox Code Playgroud)
获取匹配行数也很容易:
cut -c 1-"${#1}" | grep -cF "$1"
Run Code Online (Sandbox Code Playgroud)
或者所有匹配行的行号(行号从 1 开始):
cut -c 1-"${#1}" | grep -nF "$1" | cut -d : -f 1
Run Code Online (Sandbox Code Playgroud)
您可以将行号提供给head
并tail
获取匹配行的全文,但在这一点上,只需使用现代脚本语言(如 Python 或 Ruby)就更容易了。
(上面的例子假设 Posix grep 和 cut。他们假设要搜索的文件来自标准输入,但可以很容易地改用文件名。)
编辑:您还应该确保模式 ( $1
) 不是零长度字符串。否则cut
失败说values may not include zero
。此外,如果使用 Bash,请使用 .catchset -o pipefail
来捕获错误退出cut
。
123*_*123 10
一种使用 perl 的方法,它会尊重反斜杠
v="$1" perl -ne 'print if index($_, $ENV{"v"} )==0' file
Run Code Online (Sandbox Code Playgroud)
这会为命令设置环境变量 v,然后打印变量的索引是否为 0,即行的开头。
你也可以在 awk 中做同样的事情
v="$1" awk 'index($0, ENVIRON["v"])==1' file
Run Code Online (Sandbox Code Playgroud)
我想不出一种方法来使用grep
; ^
本身是正则表达式的一部分,因此使用它需要解释正则表达式。它使用子串匹配的琐碎awk
,perl
或什么:
awk -v search="$1" 'substr($0, 1, length(search)) == search { print }'
Run Code Online (Sandbox Code Playgroud)
要处理包含 的搜索字符串\
,您可以使用与123 的答案相同的技巧:
search="$1" awk 'substr($0, 1, length(ENVIRON["search"])) == ENVIRON["search"] { print }'
Run Code Online (Sandbox Code Playgroud)
这是一个全 bash 选项,不是我推荐 bash 进行文本处理,但它有效。
#!/usr/bin/env bash
# searches for $1 at the beginning of the line of its input
len=${#1}
while IFS= read -r line
do
[[ "${line:0:len}" = "$1" ]] && printf "%s\n" "$line"
done
Run Code Online (Sandbox Code Playgroud)
该脚本计算len
输入参数 $1的长度,然后在每一行上使用参数扩展来查看第一个len
字符是否与 $1 匹配。如果是这样,它会打印该行。
如果您$1
是纯 ASCII 并且您grep
可以-P
选择(启用 PCRE),则可以执行以下操作:
#!/bin/bash
line_start="$1"
line_start_raw=$(printf '%s' "$line_start" | od -v -t x1 -An)
line_start_hex=$(printf '\\x%s' $line_start_raw)
grep -P "^$line_start_hex"
Run Code Online (Sandbox Code Playgroud)
这里的想法是grep -P
允许正则表达式\xXX
指定文字字符,其中XX
是该字符的十六进制 ASCII 值。该字符按字面匹配,即使它是特殊的正则表达式字符。
od
用于将预期的行开始转换为十六进制值列表,然后将这些值串在一起,每个值都以\x
printf为前缀。 ^
然后在此字符串前面添加以构建所需的正则表达式。
如果您$1
是 unicode,那么这会变得相当困难,因为od
.
如果您的 grep 有 -P 选项,这意味着PCRE,您可以这样做:
grep -P "^\Q$1\E"
Run Code Online (Sandbox Code Playgroud)
请参阅此问题,如果您愿意,请参阅PCRE 文档了解详细信息。