同时提取文件中的行号和模式

同时提取文件中的行号和模式

我读了一堆文本文件来提取一些模式。我也需要行号,但必须在最终 grep 之前删除行号(但可以保存以供进一步处理,可能使用变量)。

我将解释我的分割(长单行)命令的过程,以便更好地理解:

  1. 读取文件,进行一些清理(使用删除奇怪的字符和换行符sedt)等等。以下只是许多管道清洁任务的示例:

     cat file | sed 's/,/ /g' | sed '/^$/d'
    
  2. 添加行号和制表符NL命令及更多处理和清理

     nl -nrz -w4 -s$'\t' | tr '\n\r' ' '
    
  3. 将最终所需的模式提取到 CSV 文件

     grep -Eio '.{0,0}account number.{0,15}' >> account_list.csv
    

问题是我需要使用同一行命令(不允许 while 或循环)将步骤 2 中的行号发送到完全相同的 CSV(其他列,无论顺序如何),但到目前为止没有成功。

[为了更好地理解而编辑] 考虑到我需要的行号是文件清理之前的原始行号。这个清理过程有时会删除一些段落。想象一个有一千行的文件,经过处理后我得到了一百行。新行编号错误。 [编辑结束]

经过一些处理后的示例输入:

0123 the first account number 2345356432 must be used
0345 take it just for billing purposes, not any other.
0657 Meanwhile the second account number 8623525534
0987 user is blocked until the issue is solved with

所需的输出将是:

 2345356432; 0123
 8623525534; 0657

或者

0123; 2345356432
0657; 8623525534

任何提示将不胜感激

答案1

awk在清理之前,在原始输入文件上使用:

awk '/account number [[:digit:]]+/ { match($0, "account number ([[:digit:]]+)", a); print NR ";" substr($0, a[1, "start"], a[1, "length"]); }' input

这会提取帐号并在行开头打印行号:

1;2345356432
3;8623525534

如果您想从清理后的文件中提取预处理的数字:

awk '/account number [[:digit:]]+/ { match($0, "account number ([[:digit:]]+)", a); print $1 ";" substr($0, a[1, "start"], a[1, "length"]); }' input

稍微拆分一下:

  • /account number [[:digit:]]+/确保我们只处理与“帐号”后跟数字匹配的行;
  • match($0, "account number ([[:digit:]]+)", a)再次查找模式并将匹配组的位置和长度(([[:digit:]]+),数字)存储在 array 中a
  • print NR ";" substr($0, a[1, "start"], a[1, "length"])打印记录号(IE行号;FNR如果要处理多个文件,请使用),然后是;,然后是与第一组对应的子字符串:a[1, "start"]给出其起始索引、a[1, "length"]长度(由 填充match)。

所有这些都假设每行最多有一个帐号。

第二个变体打印$1而不是NRIE文件中的第一个字段,即预处理的行号。

答案2

如果您的 grep 版本支持 Perl 正则表达式,您可以使用后视:

grep -Pnio "(?<=account number.)([0-9]{0,15})" text

答案3

考虑到您的输入和输出,awk 脚本似乎要简单得多:

gawk '/account number/ {
    nr=gensub(/.*account\s*number\s*([0-9]+).*/, "\\1", "g")
    print FNR "; " nr
}'

当然,您可能需要根据您的喜好调整帐号提取和输出格式。但你明白了。 (由于使用该gensub函数,需要 GNU awk。)

答案4

我很想使用 Perl 来实现这个目的,像这样的东西应该可以工作:

perl -ne 'print "$1; $2\n" if /^(\d+).*account number (\d+)/' input

在以一些数字 ( ) 开头^\d+并包含字符串“帐号”后跟一些数字的行上,打印第一个和第二个捕获组(括号中的部分,此处为数字)。如果您想打印 Perl 的行号概念,请使用$.代替$1

相关内容