使用终端从文件中提取文本?

使用终端从文件中提取文本?

我想处理文本主体并从文本中的特定位置提取一个整数,但我不确定如何描述那个“特定位置”。正则表达式真的让我很困惑。我花了(浪费了)几个小时阅读教程,但感觉离答案还差得很远 :(

有一堆文本可能包含也可能不包含整数(我不想要),然后有一行总是包含

id_ad=1929170&action

然后接着是一堆我不关心的垃圾,它可能包含也可能不包含一个或多个整数。

因此,直觉上我知道我只想忽略所有到(包括)的内容id_ad=,并忽略所有到(包括)的内容之后的内容&action,这样我就能得到我想要的整数。我知道我可以使用正则表达式来实现这一点。但我似乎想不通。

如果可能的话,我想从终端以一行代码的形式完成此操作。

答案1

并不是一行代码(尽管运行它的命令单行:)),但这是一个python选项:

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    text = src.read()

starters = [(i+6, text[i:].find("&action")+i) for i in range(len(text)) if text[i:i+6] == "id_ad="]
if len (starters) > 0:
    for item in starters:
        print(text[item[0]:item[1]])

该脚本首先列出 (起始) 字符串“id_ad=”与 (结束) 字符串“&action”的所有出现 (索引)。然后,它会打印出这些“标记”之间的所有内容。

从准备好的文件中提取:

“我想处理文本主体并从文本中的特定位置提取一个整数,但我不确定如何描述该“特定位置”。正则表达式真的让我很困惑。我花了(浪费了)几个小时阅读教程,但我觉得离答案还很远 :( 有一堆文本可能包含也可能不包含整数(我不想要的),然后有一行始终包含 id_ad=1929170&action 有一堆文本可能包含也可能不包含整数(我不想要的),然后有一行始终包含 id_ad=1889170&action,然后后面跟着一堆我不关心的垃圾,同样,它可能包含也可能不包含一个或多个整数。有一堆文本可能包含也可能不包含整数(我不想要的),然后有一行始终包含 id_ad=1889170&action,然后后面跟着一堆我不关心的垃圾不关心,同样,它可能包含也可能不包含一个或多个整数。有一堆文本可能包含也可能不包含整数(我不想要),然后有一行始终包含 id_ad=1929990&action"

结果是:

1929170
1889170
1889170
1929990

如何使用

将脚本粘贴到一个空文件中,保存并extract.py运行以下命令:

python3 <script> <file>

笔记

如果文本文件中仅出现一次,则脚本可以更短:

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    text = src.read()
print(text[text.find("id_ad=")+6:text.find("&action")])

答案2

例如:

 egrep "id_ad=[[:digit:]]+&action" file.txt |  tr "=&" "  " | cut -d " " -f2 

...但我确信还有更优雅的方式;-)。

一步步:

egrep "id_ad=[[:digit:]]+&action" file.txt 

扫描由文字,后跟 1 个或多个数字( 的含义,后跟文字file.txt)组成的模式(正则表达式)。将输出发送到标准输出。id_ad=[[:digit:]]+&action

tr "=&" "  " 

将字符“=”和“&”转换为两个空格。

cut -d " " -f2

打印标准输入的第二个字段(以空格分隔)。

答案3

使用 sed:

sed 's/id_ad=\(.*\)&action/\1/' filename

解释:

.*上述命令返回文件名中两个 START 字( id_ad=) 和 END 字( ) 之间的任何字符串( ) &action
\(...\)用于捕获组。\(是捕获组的开始,以 结束\)\1我们打印其组索引(我们有一个捕获组)

上述解决方案的更好的sed命令可以是这样的:

sed 's/^id_ad=\([0-9]*\)&action/\1/' filename

^行的开头。
[0-9]*:出现 0 次或多次的任意数字。
有关 sed 命令的更多信息,请参阅

使用 grep:

解释:

grep -Po '(?<=id_ad=)[0-9]*(?=&action)' filename

来自 man grep:

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.
-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

[0-9]*返回文件名中两个 START 字( id_ad=) 和 END 字( ) 之间出现 0 次或多次的任意数字( ) &action

(?<=pattern):正向后视。一对括号,左括号后跟问号、“小于”符号和等号。

(?<=id_ad=)[0-9]*id_ad=(正向后视)匹配文件名后跟的 0 个或多个数字。

(?=pattern):正向前瞻:正向前瞻结构是一对括号,左括号后跟问号和等号。

[0-9]*(?=&action):(正向预测)匹配 0 次或多次后跟 pattern( &action) 的数字,但不将 pattern( &action) 作为匹配的一部分。
阅读有关 Lookahead 和 Lookbehind 的更多信息

额外链接:
高级 Grep 主题
面向设计师的 GREP

答案4

通过模块的另一个 Python 答案re。示例取自 Jacob 的帖子。

script.py

#!/usr/bin/python3
import sys
import re
file = sys.argv[1]
L = []                                                  # Declare an empty list
with open(file) as src:
    for j in src:                                       # iterate through all the lines
        for i in re.findall(r'id_ad=(\d+)&action', j):  # extracts the digits which was present in-between `id_ad=` and `&action` strings.
            L.append(i)                                 # Append the extracted digits to the already declared empty list L. 
    for f in L:                                         # Iterate through all the elements in the list L
        print(f)                                        # Print each element from the list L in a separate new line.

运行上述脚本,

python3 script.py /path/to/the/file

例子:

$ cat fi
I want to process the body of text and extract an integer from a specific position in the text, but I'm not sure how to describe that 'particular position'. Regular expressions really confuse me. I spent (wasted) a couple hours reading tutorials and I feel no closer to an answer :( There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains

 id_ad=1929170&action There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains id_ad=1889170&action and then followed by a bunch of garbage I don't care about, again it may or may not include one or more integers. There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains

 id_ad=1889170&action and then followed by a bunch of garbage I don't care about, again it may or may not include one or more integers. There's a bunch of text which may or may not include integers (that I don't want) and then there's a line that always contains id_ad=1929990&action

$ python3 script.py ~/file
1929170
1889170
1889170
1929990

相关内容