【问题标题】:Bash script to grep through one file for a list names, then grep through a second file to match those names to get a lookup valueBash 脚本通过一个文件 grep 获取列表名称,然后通过第二个文件 grep 以匹配这些名称以获得查找值
【发布时间】:2013-08-31 17:34:06
【问题描述】:

不知何故,具体化并不能很好地转化为标题。

这是我的目标,在 cygwin 环境中使用 BASH 脚本:

  1. 读取文本文件 $filename 以获取模式和表名列表
  2. 获取架构和表名列表并在 $lookup_file 中找到匹配项以获取值
  3. 使用该值进行逻辑选择

我基本上让每个项目单独工作。我只是不知道如何将它们粘合在一起。

第一步是

grep $search_string $filename | awk '{print $1, $5}' | sed -e 's~"~~g' -e 's~ ~\t~g'

其中给出了架构{tab}表的列表

第二步是

grep -e '{}' $lookup_file | awk '{print $3}'

其中 $lookup_file 是架构{tab}表{tab}值

第三步基本上就是根据返回的值,做“某事”;提交报告、通过电子邮件发送警告、忽略它等等。

我尝试将第一部分和第二部分与 xargs 连在一起,但它会将架构和表名视为文件名并引发错误。

我缺少的胶水是什么?还是有更好的方法?

【问题讨论】:

  • awk 可以自己做 grepping,你不需要用管道 grep 给它。而且它也可以自己替换,不需要通过管道传递给 sed。
  • 请不要忘记引用文件名。喜欢grep "$search_string" "$filename"grep -e '{}' "$lookup_file"
  • 我实际上可以想到一个解决方案,但我很好奇"" 之间的数据是如何放置的。它们可以包含空格吗?其他领域呢?他们也放在"" 附近吗?它们是用空格还是制表符分隔的?
  • 既然人们在问,这里有一个来自 $filename; 的示例行。 schema{space}-{space}text{space}search_string{space}"table"。请注意,只有表名用引号括起来。文本不会包含任何需要担心的额外空格

标签: bash awk grep


【解决方案1】:
awk -v s="$search_string" 'NR == FNR { if ($0 ~ s) { gsub(/"/, "", $5); a[$1, $5] = 1; }; next; } a[$1, $2] { print $3; }' "$filename" "$lookup_file"

解释:

NR == FNR { if ($0 ~ s) { gsub(/"/, "", $5); a[$1, $5] = 1; }; next; } 以第一个文件为目标,在其上搜索有效匹配项,并将键值保存在数组 a 中。

a[$1, $2] { print $3; } 以第二个文件为目标,如果找到与文件的第一列和第二列以及数组 a 中的键匹配的值,则在其第三列中打印值。

【讨论】:

  • @MivaScott 我上面的代码应该已经为您工作了,即使步骤 gsub(/"/, "", $1); 不再需要并且可以删除。
  • 这是我必须接受的答案。比我希望的要神秘一点,但我不能拥有一切。谢谢。
【解决方案2】:
awk -v search="$search_string" '$0 ~ search { gsub(/"/, "", $5);
                                              print $1"\t"$5; }' "$filename" |
    while read line
    do
        result=$(awk -v search="\b$line\b" '$0 ~ search { print $3; } ' "$lookup_file");
        # Do "something" with $result
    done

【讨论】:

  • /"/ 可能比 "\"" 更容易使用
  • 这非常接近,除了第一个 awk 如何输出名称。我可以看到它误入歧途的地方。当我使用 sed 删除 {space} 字符时,并不是因为任何数据都有空格;这是 awk 在第 1 列和第 5 列之间放置空格的副产品。因此可以删除用于删除空格的 gsub,并且只有最后一列有引号,所以我删除了第 1 列的 gsub。但我仍然无法弄清楚如何更改 awk 打印命令以使用制表符而不是空格。希望一旦过了这个障碍,它应该是完美的。
  • 编辑在列之间放置一个 TAB。
  • 太棒了..最后的皱纹。搜索正在寻找额外的表名。因此,如果列表中有table_a,当它进行查找时,它会给出table_atable_appletable_america 的结果。我找到了一些进行完全匹配的示例,但我要么得到错误,要么没有结果。如何确保 $line 只是 /$line/
  • 我在正则表达式中添加了\b 以匹配单词边界。
猜你喜欢
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
相关资源
最近更新 更多