【问题标题】:How to start import from first numeric column in each row如何从每行的第一个数字列开始导入
【发布时间】:2014-09-12 15:14:27
【问题描述】:

我对此很陌生,所以如果我不清楚,我很抱歉,但我会尽力而为。我有一个没有从 PDF 创建的标题的文本文件。每一行都有点不同,因为第一列是人的名字(人们有不同数量的名字),名字之后是我真正关心的列。我关心的第一列中的数据总是以数字开头。例如,我的数据如下所示:

John Paul Apple     8422M   JPA
John Apple       422F   JA
John Paul of the Apple    32245F  JPOTA
John    345222R   J

我尝试使用类似的东西:

awk '{$1=""; $2=""; sub("  ", " "); print}' input_filename > output_filename

但这会导致我不想要的信息,并丢失一些我确实关心的信息。是否有将每行的第一列视为以数字开头的命令?

我的输出文件将如下所示:

8422M   JPA
422F    JA
32245F  JPOTA
345222R J

【问题讨论】:

    标签: shell awk


    【解决方案1】:

    这是一个 awk 版本:

    awk '{sub("^[^0-9]*",""); print}'
    

    如果你想让输出看起来整洁,

    awk '{sub("^[^0-9]*",""); printf "%-12s : %s\n", $1, $2}'
    

    编辑

    为了整齐地打印第三个字段,假设第二列数据的宽度永远不会超过 8 个字符,

    awk '{sub("^[^0-9]*",""); printf "%-12s : %-8s : %s\n", $1, $2, $3}'
    

    如果第 2 列的某些内容太大,它仍会被打印,将第 3 列的数据推过。 %-8s 表示在至少 8 列宽的字段中打印string,左对齐,%8s 将导致数据右对齐。 awk 使用标准 C printf 格式说明符;你也可以在 Python 中使用它们。

    【讨论】:

    • 第二行很好用!我将如何在前 2 列之后导入第三列?尝试添加 ,$3 没有成功。
    【解决方案2】:

    你可以试试grep,

    $ grep -oP '(?: |^)\K\d.*' file
    8422M   JPA
    422F   JA
    32245F  JPOTA
    345222R   J
    
    $ grep -oP '(?: |^)\K\d.*' file | column -t
    8422M    JPA
    422F     JA
    32245F   JPOTA
    345222R  J
    

    $ grep -o '[0-9].*' file
    8422M   JPA
    422F   JA
    32245F  JPOTA
    345222R   J
    

    【讨论】:

    • 非常感谢。我正在尝试这个没有成功。我试着做: cat input.txt | grep -oP '(?: |^)\K\d.*' > output.txt 但我只得到一个空白文件。
    • grep -oP '(?: |^)\K\d.*' input.txt 的输出是什么?
    • 输出是:用法:grep [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [- -binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...] 我正在从终端执行此操作,以防万一。非常感谢。
    • 尝试了更新,仍然得到与以前完全相同的输出。
    • 尝试不使用E,即grep -o '[0-9].*' file
    【解决方案3】:

    假设名称中没有数字(“从行首删除所有不是数字的内容”),

    $ sed 's/^[^0-9]\{1,\}//'  input.txt  
    8422M   JPA
    422F   JA
    32245F  JPOTA
    345222R   J
    

    或者,以下任何一个也可以工作(简化的 sed + perl 等效项):

    $ sed 's/^[^0-9]*//'   input.txt
    $ perl -pe 's/^[^0-9]*//'  input.txt
    

    【讨论】:

    • 这个:“\{1,\}”表示“一个或多个”;如果是老sed看不懂,也可以用's/^[^0-9][^0-9]*//'
    • 谢谢!这给了我正确的输出,直到它到达某人的名字中有一个“-”的行,然后我得到 sed:RE 错误:非法字节序列
    • @Lucho 真的吗?什么操作系统? (Solaris?试试gsed)在Linux上,它可以工作:echo 'A-B-C 1234 ABC' | sed 's/^[^0-9]\{1,\}//' => 1234 ABC` `
    • 我在 OS X 上使用终端。再次感谢!
    • ..添加了简化的 sed 和 perl 等效项...不确定 mac 是否会遇到这些问题。在 OSX 上,我确实使用/推荐 macports,以便我拥有所有常见(核心)实用程序的 GNU 变体。 macports.org
    猜你喜欢
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2020-05-21
    • 2019-11-01
    • 2021-08-21
    相关资源
    最近更新 更多