【问题标题】:Finding the position in a file serially where all numbers from a list have been found连续查找文件中已找到列表中所有数字的位置
【发布时间】:2023-03-06 06:27:01
【问题描述】:

我可能对这个标题的措辞有误 - 对此我深表歉意。 我有一个包含数字列的(大)文本文件。我可以在命令行上从文件中提取列。我想将此列通过管道传输到一个命令中,在该命令中我给出一个数字列表,它告诉我列表在哪个(文件)位置匹配 - 这意味着列表中的所有数字至少在列中出现过一次。

例如,我的列表有以下数字1 2 3

提取的列是(注意我已经输入了不存在的行号)......

line1: 1
line2: 2
line3: 2
line4: 1
line5: 3
line6: 3
line7: 2

所以在这种情况下,它应该返回 5 (= line5)。

为清楚起见的另一个例子....

我从文件中提取的列在换行符上具有以下序列...

1 2 2 1 3 3 2 ...

我需要打印列表中所有数字都匹配的行号,我的列表是1 2 3。所以在这种情况下,它应该说第 5 行,此时它已找到所有 1、2 和 3。

【问题讨论】:

  • 给出最少的输入和预期的输出以便清晰理解。
  • 而以上不是最小的吗?
  • 我猜你需要更好地解释它:) 可能是另一个例子
  • 1 2 3 的数字如何产生5,即您指出的第 5 行?
  • 这是找到所有列表编号 1、2 和 3 的行号。

标签: bash awk sed terminal


【解决方案1】:

我的数据如上:

$ head -2 foo
line1: 1
line2: 2

在 awk 中。遍历每一行,并用新号码提醒最后一行。最后打印出来:

$ awk '
!($2 in a) {  # if the value has not been seen before
    a[$2];    # remember it in array a
    i=NR}     # also remember the number of record (NR) with unseen data
END {         # in the end
    print i   # print the i from above
}' foo
5

如果文件只有数字,而不是line1:等,请将$2更改为$1

编辑:

如果你想为程序提供你想找到的数字,使用这个:

$ awk -v these="1 2 3" '  # pass the numbers to the program in variable
BEGIN {
    split(these,a," ")    # split them to a array
} 
($2 in a) {               # if found number is in a
    i=NR;                 # remember the NR
    delete a[$2]          # delete entry from array a
} 
END { print i }           # in the end print the last found NR
' foo
5

如果没有找到所有号码,它会失败并打印最后找到的号码的NR。可以通过以下方式实现:END { for (j in a) exit; print i}

【讨论】:

  • 您介意更详细地解释一下语法吗,我可以将其用作更多情况的模板。
  • 这是一个很好的逻辑,正在思考和尝试更复杂的逻辑。但是,当用户不想要 $2 中的所有唯一条目,而只想要一个子集说 1 2 在这种情况下它应该返回行号 2 时,你如何管理,但你的逻辑将处理直到所有找到唯一的条目了吗?
  • 正在考虑一种方法让用户在 bash 变量中输入并将其拆分为一个数组,并在处理每个新行之前检查是否所有元素都已映射
  • @JamesBrown,它如何适应包含任意数字的列表?
  • 查看我的编辑。请记住,没有检查给定数字是否存在于文件中。这就是为什么它会打印出最后找到的所需数字的 NR。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 2020-12-02
相关资源
最近更新 更多