Bash参数替换混乱(pdfgrep、regex、换行符等)

Bash参数替换混乱(pdfgrep、regex、换行符等),regex,bash,Regex,Bash,我需要使用pdfgrep跨多条线匹配一个图案 pdfgrep -in -C line 'CHAPTER 1'[$'\n'][$' ']*'THIS IS THE TITLE' ~/temp.pdf 工作正常,输出正常 12: CHAPTER 1 THIS IS THE TITLE 现在 不再工作了,什么也没给我。我猜参数替换是有问题的,但我不知道发生了什么。有人能帮忙吗 背景资料: 来自“ma

我需要使用pdfgrep跨多条线匹配一个图案

pdfgrep -in -C line 'CHAPTER 1'[$'\n'][$' ']*'THIS IS THE TITLE' ~/temp.pdf
工作正常,输出正常

12:                                 CHAPTER 1
                  THIS IS THE TITLE
现在

不再工作了,什么也没给我。我猜参数替换是有问题的,但我不知道发生了什么。有人能帮忙吗

背景资料:

来自“man pdfgrep”


“”匹配任何字符,包括换行符。

您正在使用额外的
字符:

"'${pattern:0:9}'[$'\n'][$' ']*'${pattern:12:${#pattern}}'"
 ^              ^              ^                         ^
另外,您在双引号中使用了
$'\n'
$'
,这防止了它们的扩展

正确的表达方式是:

"${pattern:0:9}"[$'\n'][$' ']*"${pattern:12:${#pattern}}"
事实上:

$ echo 'CHAPTER 1'[$'\n'][$' ']*'THIS IS THE TITLE'
CHAPTER 1[
][ ]*THIS IS THE TITLE

$ pattern="CHAPTER 1 - THIS IS THE TITLE"
$ echo "${pattern:0:9}"[$'\n'][$' ']*"${pattern:12:${#pattern}}"
CHAPTER 1[
][ ]*THIS IS THE TITLE
请注意,当给定这两个表达式时,
echo
的输出是等效的(如果操作正确,
echo
不应返回Bash表达式,它应返回最终字符串)


这不是必需的,但作为最佳实践,您应该引用
*
[
]
字符(感谢您的注意)。另外,
$”
在这里也很无用:

"${pattern:0:9}["$'\n'"][ ]*${pattern:12:${#pattern}}"
                ^     ^  ^

这将防止全局扩展(这在您的情况下不太可能发生,但仍然需要注意)。

$“\n”在字符串双引号时不会插入换行符:

prompt $ echo "$'\n'"
$'\n'
prompt $ echo $'\n'
不要在字符串周围使用双引号:

prompt $ a='abcd'$'\n''efgc'
prompt $ echo "$a"
abcd
efgc

另外,你的正则表达式看起来很奇怪。为什么在\n和\s之间使用方括号

您的
echo
与输出不匹配-您使用的是
pattern1
而不是
pattern
。这仅仅是问题中的一个输入错误,还是事实上也是如此。我被骗了,因为我不得不在“第1章”和“这是标题”周围加引号,以避免与空格混淆,我认为替换完全相同的字符串会起作用;它们形成了shell可以解释的有效模式(尽管这种模式不太可能与文件名匹配。
'CHAPTER 1['$'\n'].*这是标题…
我从“CHAPTER 1\n*这是标题”~/temp.pdf中更简单的
pdfgrep-开始,然后在“CHAPTER 1$'\n'$'.*这是标题”~/temp.pdf
,然后
pdfgrep-在“第1章[$”\n'][$”*中,这是标题“~/temp.pdf
,但似乎什么都不起作用。我用额外的引号重新构建了它,但我真的不明白为什么这些更简单的表达式不起作用。我再试了一次,更简单的
pdfgrep-在“第1章[$”\n'$”*中,这是标题~/temp.pdf
有效!@橡皮擦:如果您想进一步简化它,请删除
$'
并使用
“第1章”$'\n'.*这是标题”
取而代之。是的,我做到了。我开始了解shell脚本的诀窍,在某些情况下,由于模式全球化、正则表达式、强引用、弱引用、许多替换……有时都在一起,因此非常棘手。Thx,Luca。
prompt $ echo "$'\n'"
$'\n'
prompt $ echo $'\n'
prompt $ a='abcd'$'\n''efgc'
prompt $ echo "$a"
abcd
efgc