【问题标题】:Extract lines matching result from text file从文本文件中提取匹配结果的行
【发布时间】:2011-12-14 10:29:55
【问题描述】:

我需要从文本文件中提取文件名,而文本文件的输出没有字体。

所以你可以从下面的输出文件中看到,我需要在第一个结果之后打印出没有字体的结果?所以只有最后一个结果在这个输出中有字体

这有意义吗 - Grep、Sed 或 Awk 会是答案吗

因此需要下面文本文件的输出,显示 **START 和 **END 中的 PDf 中没有字体

******************START***********************
name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
/home/user1/Documents/temp1.pdf
******************END***********************
******************START***********************
name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
/home/user1/Documents/temp2.pdf
******************END***********************
******************START***********************
name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
BAAAAA+TimesNewRomanPS-BoldMT        TrueType          yes yes yes     14  0
CAAAAA+TimesNewRomanPSMT             TrueType          yes yes yes      9  0
/home/user3/Documents/temp file.pdf
******************END***********************

【问题讨论】:

  • 你解决这个问题的程度如何?
  • 只需要包含在 *START*END 中且没有提及字体的 PDF 文件名。我现在正在尝试 awk,但没有乐趣:-(
  • @Grimlockz 您可以编辑您的问题,根据您的输入示例添加预期的输出吗?你的评论我也不清楚。 “没有提到任何字体。”....

标签: bash shell awk grep


【解决方案1】:

如果前一行以- 开头,则打印任何包含“.pdf”的行。

[me@home]$ awk '{if (st && match($0,".pdf")){print $0}; st=match($0,"^-")}' in.txt
/home/user1/Documents/temp1.pdf
/home/user1/Documents/temp2.pdf

这不是通用解决方案,但可以使用您提供的输入数据。我可以想象几种可能会失败的极端情况,但这完全取决于您输入文件的规范。


更新

(基于您在下面的 cmets 中发布的脚本)如果您尝试做的只是识别没有嵌入字体的 PDF 文件,这可能有效:

MAGNUM="/mnt/network/User\ 1\ PDF\ 06.12.11/"
has_no_fonts() {
    COUNT=$(pdffonts "$1" 2> /dev/null | wc -l)
    exit $(( $COUNT - 4 ))
}
export -f has_no_fonts
find "$MAGNUM" -type f -name "*.pdf" -exec bash -c 'has_no_fonts "{}"' \; -print

以下是脚本的细分:

  • 检测嵌入的字体数量。如果pdffonts 在没有嵌入字体的情况下返回一个特定的值,那会很简单,但事实并非如此。因此,我们计算输出行数并减去 2(标题行)以确定嵌入字体的数量

    COUNT=$(pdffonts "$1" 2> /dev/null | wc -l) # number of output lines
                                                # exactly 2 if no fonts
                                                # exactly 0 if there are errors
    exit $(( $COUNT - 2 ))  # exit 0 (success) if and only if PDF has no fonts
    
  • 导出bash函数,以便在子shell中使用。

    export -f has_no_fonts
    
  • 查找 pdf 文件并仅在 PDF 有效且没有字体时打印出名称

    find .....  -exec bash -c 'has_no_fonts "{}"' \; -print
                      -------                        -------
                          |                             |
              -exec cannot run bash functions     Will only print 
               so run in a bash subshell       filename if prev command exit with 0
    

如果你喜欢单行,整个脚本可以写成:

find "$MAGNUM" -name "*.pdf" \
    -exec bash -c 'exit $(($(pdffonts "{}" 2> /dev/null |wc -l) - 2))' \; -print

【讨论】:

  • 干杯现在测试这个,它似乎工作谢谢 - #!/bin/bash SAVEIFS=$IFS IFS=$(echo -en "\n\b") MAGNUM=/mnt/network/User\ 1\ PDF\ 06.12.11/ for f in $(find $MAGNUM -type f -name "*.pdf") do echo "******************START***********************" pdffonts $f echo "$f" echo "******************END***********************" done > output.txt # restore $IFS IFS=$SAVEIFS 如果有帮助,这是获取 PDF 信息的脚本
  • @Grimlockz 很高兴它有帮助。顺便说一句,如果您使用该脚本更新您的问题以显示输入文件的来源以及您想要实现的目标,它可能会帮助其他读者。附言查看替代解决方案的更新答案(假设您没有将output.txt 用于其他任何事情)。
  • 非常感谢并注意到,将继续更新 - 新脚本看起来很棒,但由于文件夹文件名中的空格,它很难找到文件夹:-(
【解决方案2】:

这可能对你有用:

sed -n '/^\*/,//{H;/\*END\*/{x;s/\n/&/6;t;s|[^/]*\([^\n]*\).*|\1|p}}' in.txt
/home/user1/Documents/temp1.pdf
/home/user1/Documents/temp2.pdf

解释:

  1. 关注以* 开头的行之间的行
  2. 将此类行存储在保持空间 (HS) 中。
  3. 当我们到达 HS 的结束分隔符时。
  4. 检查是否有 6 个或更多换行符,即必须有字体的条目,如果有,则排除。
  5. 删除所有不必要的文本并打印出来。

或者在紧要关头:

sed -n '/^\*/,//{H;/\*END\*/{x;s|[^/]*-\n\(/[^\n]*\).*|\1|p}}' in.txt

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 2019-12-21
    • 2017-12-15
    • 2014-09-11
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多