【问题标题】:Get Text after word at specific position在特定位置获取单词后的文本
【发布时间】:2019-01-14 05:51:31
【问题描述】:

我有这样的文件

TT;12-11-18;text;abc;def;word
AA;12-11-18;tee;abc;def;gih;word
TA;12-11-18;teet abc;def;word
TT;12-11-18;tdd;abc;def;gih;jkl;word

我想要这样的输出

TT;12-11-18;text;abc;def;word
TA;12-11-18;teet abc;def;word

如果word 出现在日期12-11-18 之后的位置5,我想获得它。如果在第 6 位或第 7 位之后发现它,我不希望发生这种情况。位置计数从日期12-11-18开始 我想试试这个命令

cat file.txt|grep "word" -n1

这将打印与此模式word 匹配的所有匹配项。我应该如何解决我的问题?

【问题讨论】:

  • 您的问题和建议的输出不符合要求。您声明您希望“单词”一词位于字段 5 字段中的行比匹配“12-11-18”的字段更远。您的第二行不符合此标准。
  • 我只想要那些字段在第 5 位之后的行。我不想要它在第六或第七位置的那些行。如果我想在任何位置匹配单词,我会简单地使用grep "word" file.txt 命令
  • 第五位怎么定义?例如。在您的预期输出中,您将TT;12-11-18;text;abc;def;word 其中word 在字段6 中和12-11-18 在字段2 中,所以这是4 位置。而在第二行,TA;12-11-18;teet abc;def;word 则相差 3 个位置。还是您的意思是word 应该在字段5 中。在这种情况下,您的第二行不正确,因为它在字段 4 中。
  • 样本输入的每一行都包含 word 并且您的预期输出包括 word 未出现在位置 5 的行。您很难帮助您找到正确的解决方案。
  • 抱歉,我的问题让您感到困惑。我在问题中提到我想要word 在它出现在日期的第 5 位之后。我从数据12-11-18开始计数。

标签: linux awk grep


【解决方案1】:

试试这个(GNU awk):

awk -F"[; ]" '/12-11-18/ && $6=="word"' file

sed一:

sed -n '/12-11-18;\([^; ]*[; ]\)\{3\}word/p' file

或者 grep 使用基本相同的正则表达式(不同的转义):

grep -E "12-11-18;([^; ]*[; ]){3}word" file

[^; ] 表示任何不是;(空格)的字符。<br>* 表示匹配前一个字符/组的任何重复。
-- [^; ]* 表示不包含; 或空格的任意长度字符串,[^; ] 中的^ 为取反。

[; ] 表示; 或空格,一个 出现。
() 是将以上这些组合在一起。
{3} 是匹配前者的三个重复角色/组。

整体([^; ]*[; ]){3}表示;/空格分隔的三个字段包括分隔符。

正如@kvantour 指出的那样,如果一个地方可能有多个空格,则它们可能有问题。
要将多个空格视为一个分隔符,则:

awk -F"(;| +)" '/12-11-18/ && $6=="word"'

grep -E "12-11-18;([^; ]*(;| +)){3}word"

或 GNU sed(posix/bsd/osx sed 不支持|):

sed -rn '/12-11-18;([^; ]*(;| +)){3}word/p'

【讨论】:

  • 你能解释一下这个表达式([^; ]*[; ]){3}吗?
  • @Sarah 已更新答案。
  • 这不是一个好的答案,因为一行中有多个空格可能会破坏命令。
  • @kvantour 已更新。不过,这是一件棘手的事情,最大限度地考虑/兼容性交易与准确性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多