gpt4 book ai didi

bash - 在文件 b 中查找文件 a 中的单词并输出文件 a 中缺失的单词匹配项

转载 作者:行者123 更新时间:2023-11-29 09:42:20 25 4
gpt4 key购买 nike

我有两个文件,我正在尝试对其运行 find/grep/fgrep。我一直在尝试几种不同的命令来尝试获得以下结果:

文件A

hostnamea
hostnameb
hostnamec
hostnamed
hostnamee
hostnamef

文件B

hostnamea-20170802
hostnameb-20170802
hostnamec-20170802.xml # some files have extensions
020214-_hostnamed-20170208.tar # some files have different extensions and have different date structure
HOSTNAMEF-20170802

*关于文件- date=20170802 - 大多数文件都有这种日期格式 - 有些有不同的日期格式 *

FileA 是我的控制文件 - 我想用整个单词 hostnamea-f 搜索 fileb 并匹配 fileb 中的 hostnamea-f 并输出不匹配的filea 到终端的输出中以在 shell 脚本中使用。

对于这个例子,我做的是 hostnamee 不在 fileb 中。我想运行一个 fgrep/grep/awk - 任何可以为此工作的东西 - 并且只从 filea 输出丢失的 hostnamee

我可以让它工作,但它并没有特别满足我的需要,如果我交换它,我什么也得不到。

user@host:/netops/backups/scripts$ fgrep -f filea fileb -i -w -o
hostnamea
hostnameb
hostnamec
hostnamed
HOSTNAMEF

很酷 - 我在文件 B 中找到了匹配项,但如果我尝试反转它会怎么样。

host@host:/netops/backups/scripts$ fgrep -f fileb filea -i -w -o
host@host:/netops/backups/scripts$

我尝试了几种不同的命令,但似乎无法正确执行。我使用 -i 忽略大小写,-w 匹配整个单词和 -o

我找到了某种解决方法,但希望有一种更优雅的方法可以使用 awk、egrep、fgrep 或其他命令执行此操作。

user@host:/netops/backups/scripts$ fgrep -f filea fileb -i -w -o >   test
user@host:/netops/backups/scripts$ diff filea test -i

5d4<主机名

最佳答案

你可以

  • 在 b 中寻找 a 的“唯一匹配”,即 -o
  • 将结果用作在 a 中查找的模式,即 -f-
  • 只列出不匹配的,即-v

代码:

grep -of a.txt b.txt | grep -f- -v a.txt

输出:

hostnamee
hostnamef

不区分大小写的代码:

grep -oif a.txt b.txt | grep -f- -vi a.txt

输出:

hostnamee

编辑:
作为对 Ed Morton 有趣输入的回应,我将示例输入变得有些“更难”,以测试针对子字符串匹配和正则表达式事件字符(例如“.”)的稳健性:

a.txt:

hostnamea
hostnameb
hostnamec
hostnamed
hostnamee
hostnamef
ostname
lilihostnamec
hos.namea

b.txt:

hostnamea-20170802
hostnameb-20170802
hostnamec-20170802.xml # some files have extensions
020214-_hostnamed-20170208.tar # some files have different extensions and have different date structure
HOSTNAMEF-20170802
lalahostnamef
hostnameab
stnam

这让事情变得更有趣。我提供这种不区分大小写的解决方案:

grep -Fwoif a.txt b.txt | grep -f- -Fviw a.txt
  • 附加的 -F,意思是“没有正则表达式技巧”
  • 附加-w,意思是“整词匹配”

假设接受以下“要求”更改,我发现输出非常令人满意:
“a”中的主机名仅匹配“b”的部分,如果所有相邻的 _(和其他“单词字符”始​​终被视为主机名的一部分。
(注意 hostnamed 的附加输出行,现在在“b”中找不到了,因为在“b”中,它前面有一个 _。)
为了匹配前面/后面有其他单词字符的有效主机名的可能出现,“a”中的列表必须明确命名这些变体。例如。必须列出“_hostnamed”才能在输出中不包含“hostnamed”。(运气好的话,这对于 OP 来说甚至是可以接受的,那么推荐这个扩展的解决方案;为了对“EdMortonish 陷阱”的鲁棒性。Ed,请认为这是对你有趣的输入的赞美,这并不意味着以任何方式消极。 )

“讨厌的”a 和 b 的输出:

hostnamed
hostnamee
ostname
lilihostnamec
hos.namea

我不确定 _ 的更改处理是否仍然符合 OP 目标(如果不符合,在 OP 范围内第一个不区分大小写的解决方案是令人满意的)。_是“字母字符”的一部分,可用于“全字匹配”-w。更详细的正则表达式控制在某些时候超出了 grep,正如 Ed Morton 提到的那样,使用 awk、perl(用于受虐脑锻炼的 sed,我喜欢的那种)是合适的。

在 Windows 上使用 GNU grep 2.5.4。文件 a.txt 和 b.txt 包含您的内容,但我确保它们具有 UNIX 行尾,这很重要(至少对于 a,可能不是 b)。

关于bash - 在文件 b 中查找文件 a 中的单词并输出文件 a 中缺失的单词匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45463483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com