【问题标题】:Bash: how to print the files that feature a specific given word in any line at a given location?Bash:如何在给定位置的任何行中打印具有特定给定单词的文件?
【发布时间】:2022-01-21 00:09:02
【问题描述】:

是否可以编写一个带有 2 个参数的脚本:word 表示要在目录的文件中搜索的任何单词,n 表示该单词必须在该文件的任何行中的位置,以及最终只打印在任何行的那个位置包含该单词的文件?

到目前为止我的代码是:

word=$1
for files in .
do
    grep -rl "$word" 
done

但是,这只会打印包含该单词的文件,我不确定如何实现其余部分。

【问题讨论】:

  • 单词之间有哪些可能的分隔符?
  • 我相信只是空格
  • “我相信”:你必须确定
  • 请发布一些带有相关预期输出的示例数据。不要将它们作为 cmets、图像、表格或非现场服务的链接发布,而是使用文本并将它们包含在您的原始问题中。此外, n 表示该单词必须位于的位置n 行或位置在文件中某个特定的 ro 或起始字符上还是什么?谢谢。
  • 您的示例程序没有两个参数。

标签: bash shell


【解决方案1】:

您的循环似乎有点奇怪,您希望遍历所有文件,而不是您提供的一组内容(这是一个包含单个条目的集合,.)。一点用处都没有。

所以, for file in * 会更有意义。然后,使用 ${file} 变量!你甚至没有在你的 for 循环中对它做任何事情!这也没有意义。

例如,你可以

  1. 使用read 从文件中获取行(关于如何使用 bash 从文件中读取行的数千个示例)
  2. 使用cut选择位置
  3. 使用[[ / ]] 测试该位置的字符串,如果成功
  4. 打印文件名并跳到下一个文件。

或者,学习一些正则表达式。不知道你有哪个版本的grep,但是“从行的开头,找到有N个repititions方案的东西”除了定界符+一个单词定界符后跟单词Im的任何repitititon寻找”并不难。

类似,在第五个单词中寻找“芥末”:

words_before=4
word="mustard"
# idea is to get the sed expression '/^\([^ ]\+ \)\{words_before\}word/!{qerror_code}'
sedtemplate_start='/^\([^ ]\+ \)'
sedtemplate_end='/!{q100}'
sedtemplate="${sedtemplate_start}\\{${words_before}\\}${word}${sedtemplate_end}"
#.... open all files, go through all lines
  ( echo "${this_line}" | sed -n "${sedtemplate}" ) && echo "${file}"

【讨论】:

    【解决方案2】:

    如果我理解您要正确执行的操作,那么正确的方法是(未经测试):

    #!/usr/bin/env bash
    
    awk -v word="$1" -v pos="$2" -v ORS='\0' '$pos == word { print FILENAME; nextfile }' * |
    xargs -0 cat
    

    假设您的 awk 支持 nextfile 和打印 \0(例如 GNU awk)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多