【问题标题】:Grep (fgrep) bash exact match end of lineGrep (fgrep) bash 精确匹配行尾
【发布时间】:2015-05-31 14:18:39
【问题描述】:

我有下面的示例文件

d41d8cd98f00b204e9800998ecf8427e  /home/abid/Testing/FileNamesTest/apersand $ file
d41d8cd98f00b204e9800998ecf8427e  /home/abid/Testing/FileNamesTest/file[with square brackets]
d41d8cd98f00b204e9800998ecf8427e  /home/abid/Testing/FileNamesTest/~$tempfile
017a3635ccb76250b2036d6aea330c80  /home/abid/Testing/FileNamesTest/FileThree
217a3635ccb76250b2036d6aea330c80  /home/abid/Testing/FileNamesTest/FileThreeDays
d41d8cd98f00b204e9800998ecf8427e  /home/abid/Testing/FileNamesTest/single quote's

我想 grep 文件的最后一部分(文件名),但我想要完全匹配该行的最后一部分(文件名)

grep FileThree$ files.md5
017a3635ccb76250b2036d6aea330c80  /home/abid/Testing/FileNamesTest/FileThree

返回一个完全匹配并且没有找到我所追求的“FileThreeDays”,但由于某些文件名包含方括号,我不得不使用 grep -F 或 fgrep。但是像上面那样使用 fgrep 不起作用,它什么也不返回。

如何使用 fgrep 精确匹配行的最后一部分,同时仍然尊重上面的特殊字符 ~ / $ / ' / [ ] 等...或使用 awk 的任何其他方法...

进一步......

使用 fgrep 而不返回这两个文件我只想要完全匹配(使用上面的 $ 和 grep),但是 $ 和 fgrep 不返回任何内容。

 grep -F FileThree files.md5
017a3635ccb76250b2036d6aea330c80  /home/abid/Testing/FileNamesTest/FileThree
217a3635ccb76250b2036d6aea330c80  /home/abid/Testing/FileNamesTest/FileThreeDays

【问题讨论】:

  • 您最好使用常规 grep 并转义需要使用 \ 转义的字符。我在下面发布了一个替代答案。
  • 这适用于您上面的示例文件:fgrep -w FileThree files.md5。如果您还有一个名为FileThree 的目录,它就会中断。尽管如此,-w 在很多情况下都能让你的生活变得更简单。

标签: bash awk grep


【解决方案1】:

我无法从您的问题中说出所有细节,但听起来您可以使用 grep 并转义特殊字符:grep 'File\[Three\]Days$'

不过,如果您想使用fgrep,您可以使用一些tr 技巧来帮助您。如果你想要的只是文件名(没有目录名),你可以这样做

cat files.md5 | tr '/' '\n' | fgrep FileThreeDays

tr 命令将斜杠替换为换行符,因此它将每个文件名放在自己的行上。这意味着fgrep 只会在搜索 FileThreeDays 时找到文件名。

如果您想要完整的文件名和目录,这有点棘手,但类似的方法会起作用。假设 SHA 和文件名之间总是有一个双空格,并且其中没有任何包含双空格或制表符的文件名,您可以尝试以下操作:

sed 's/  /\t' files.md5 | tr '\t' '\n' | fgrep FileThreeDays

sed 命令将双空格转换为制表符。 tr 命令将这些制表符转换为换行符(与上面的技巧相同)。

【讨论】:

  • 不幸的是,我将为数百万个文件执行此操作,并且我注意到带有双空格的文件。我也需要 md5,所以不要认为第一种方法会起作用。也不确定是否可以选择转义,因为由于涉及的文件数量,我必须以某种方式编写脚本
【解决方案2】:

我会使用awk:

awk '{$1="";print}' file

$1="" 将第一列剪切为空字符串,print 打印修改后的行 - 现在只包含文件名。

但是,这会在每行的开头留下一个空格。如果您关心它并想将其删除,请将输出字段分隔符设置为空字符串:

awk '{$1="";print}' OFS="" file

【讨论】:

  • 我可能应该提到我需要整行,因为我需要文件名中的 md5
  • 那么你想要grep -F(固定字符串)。使用-F时不需要引用特殊字符
  • grep -F 的问题见上文
  • 如果您希望脚本可靠地转义正则表达式元字符,请选中此选项:stackoverflow.com/questions/29613304/… 您也可以将其用于 grep。这是你要找的吗?
猜你喜欢
  • 2022-01-19
  • 2021-03-19
  • 1970-01-01
  • 2017-06-03
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多