regex - 提取短语后的所有文本,然后在每行的开头添加文件名?

标签 regex perl sed

我正在从事一个包含约 3k 文本文档的文献计量学项目,我正在尝试弄清楚如何从非结构化文本获取引文列表。格式变化很大,但它们都以引用的作品结尾。到目前为止,我想出了这个:

sed -n '/Works Cited/,$p' Jones.txt > newfile.txt

在所有 ~3k 文档上运行之后,我会将它们全部组合起来进行分析。但是知道哪些行/引文来自哪个文件是有意义的。所以我最好的猜测是这将涉及 2 个步骤:

  1. 提取 Works Cited 短语之后的行。
  2. 在每行的开头插入文件名。 (没有标准的元数据结构,甚至没有一致的行来显示作者、标题等。)

例如,对于名为 Jones.txt 的文档:

...Vivamus fringilla dapibus volutpat. Phasellus nec mattis orci, vitae ornare >tellus. Nunc at porta libero. Cras non ipsum id justo auctor ullamcorper. Lorem >ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec nulla tincidunt, >venenatis nisi a, pharetra neque. Morbi euismod id mauris vitae imperdiet. Nam >sagittis mattis urna vel consectetur. Integer rhoncus leo at sagittis >sollicitudin.

Works Cited

Jones, Ted. Biology. New York: Penguin, 2009.

Smith, Mary. "Butterflies and Biology." Journal 21.2 (2013): 1-10.

我想制作这个:

Jones.txt, Jones, Ted. Biology. New York: Penguin, 2009.

Jones.txt, Smith, Mary. "Butterflies and Biology." Journal 21.2 (2013): 1-10.

这可能吗?有没有更好的方法来考虑它?我尝试在 SO 和其他地方搜索解决方案,但也许我没有在寻找正确的短语。这在 sed、perl 等中最好吗?解决方案会更改为运行 *.txt 而不仅仅是 Jones.txt 吗?

我们将不胜感激任何帮助。

-联合会

最佳答案

使用 GNU awk

您没有提及您的操作系统,但假设您可以访问 GNU awk,请尝试:

$ awk 'FNR==1{f=0} f && /./{printf "%s, ", FILENAME} f{print} /Works Cited/{f=1}' *.txt

Jones.txt, Jones, Ted. Biology. New York: Penguin, 2009.

Jones.txt, Smith, Mary. "Butterflies and Biology." Journal 21.2 (2013): 1-10.

请注意,在此解决方案中,您可以通过上述示例中的 *.txt 和 GNU awk 在命令行上一次指定所有文件名在从一个文件切换到下一个文件时更新变量 FILENAME

工作原理:

  • FNR==1{f=0}

    在每个文件的第一行,将标志 f 设置为零,表示我们还没有看到该文件的 Works Cited 行。

  • f &&/./{printf "%s, ", FILENAME}

    如果标志 f 非零(意味着 Works Cited 已经被看到)并且如果该行是非空白的(至少有一个字符在行),然后打印文件名,后跟一个逗号和一个空格。

  • f{print}

    如果标志 f 不为零,则打印整行。

  • /引用作品/{f=1}

    如果此行包含 Works Cited,则将标志 f 设置为 1。

FILENAME 变量是 GNU 扩展。

非 GNU awk

对于不支持 FILENAMEawk 版本,我们可以使用 shell 循环,设置 awk 变量 name 依次为每个文件的名称:

for f in *.txt
do 
    awk -v name="$f" 'f && /./{printf name ", "} f{print} /Works Cited/{f=1}' "$f"
done

使用sed

如果你真的必须使用 sed,试试:

for f in *.txt
do
    sed -n '/Works Cited/,${/Works Cited/d; /./ s/^/'"$f, /;p}" "$f"
done

如果您确定您的文件名不包含任何 sed 事件字符,则此方法是可以接受的。

关于regex - 提取短语后的所有文本,然后在每行的开头添加文件名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28036252/

相关文章:

Javascript 正则表达式 : Best Buy product ID from URL

linux - 如何使用 ESXi 5.1 运行/测试 VMware Perl SDK?

windows - Perl + Apache + CGI

linux - 如何使用 sed 在现有文件的开头添加 UTF-16 字符?

regex - 如何在 Linux 中查找和替换正则表达式模式?

regex - 我的URL重写规则中出现500个内部服务器错误

python - 使用动态正则表达式匹配字符串中的整个单词

java - 需要具有动态值的正则表达式

perl - 测试 Catalyst URI

linux - 如何只更改文件中的一个参数