以特定方式格式化文本文件

如何解决以特定方式格式化文本文件

我有一个巨大的文本文件内容如下:

1|ROW1|IDA|IDB|Z|OP
2|ROW2|IDA|IDC|IDF|IDG|Z|OP
3|ROW3|IDA|IDC|IDF|Z|OP

我想通过像这样展平 ID 列来格式化它:

1|ROW1|IDA|Z|OP
1|ROW1|IDB|Z|OP
2|ROW2|IDA|Z|OP
2|ROW2|IDC|Z|OP
2|ROW2|IDF|Z|OP
2|ROW2|IDG|Z|OP
3|ROW3|IDA|Z|OP
3|ROW3|IDC|Z|OP
3|ROW3|IDF|Z|OP

在脚本中是否有任何简单的方法可以做到这一点?还是我需要编写一个小程序来读取每一行并通过正则表达式匹配一行的每一列?

谢谢你的建议

解决方法

如果你愿意考虑,你可以这样做:

awk -F'|' '{
    last = 2
    for(i = 3; i <= NF; ++i) {
        if($i~/^ID/) last = i;
        else break;
    }
    for(i = 3; i <= last; ++i) {
        printf("%s|%s|%s",$1,$2,$i);
        for(j = last + 1; j <= NF; ++j) {
            printf("|%s",$j);
        }
        printf("\n");
    }
}'

对于字段由 |-F'|' 参数)分隔的每一行,这是这样做的:

  • 第一个循环查找以 ID/^ID/ 部分)开头的最后一个字段。
  • 下一个循环遍历 ID 字段并打印字段 1 和 2,然后是当前的 ID 字段。
  • 内部循环打印 ID 字段之后的所有字段。

一个可能更易于阅读和维护的版本:

awk -F'|' '{
    last = 2;
    for(i = 3; i <= NF; ++i) {
        if($i~/^ID/) last = i;
        else break;
    }

    last_fields = ""
    for(i = last + 1; i <= NF; ++i) {
        last_fields = last_fields "|" $i;
    }

    for(i = 3; i <= last; ++i) {
        printf("%s|%s|%s%s\n",$i,last_fields);
    }
}'
  • 第一个循环查找以 ID 开头的最后一个字段。
  • 第二个循环从最后一个 last_fields 字段之后的字段中构建一个变量 (ID)
  • 第三个循环打印字段 1、2、当前 ID 字段,然后是 last_fields
,

我会在这里使用带有 csv 模块的 Python 脚本:

with open('input.txt') as fdin,open('output.txt','w',newline='') as fdout:
    rd = csv.reader(fdin,delimiter='|')
    wr = csv.writer(fdout,delimiter='|')
    for row in rd:
        for item in row[2:-2]:
            _ = wr.writerow(row[:2] + [item] + row[-2:])
,

这是一个使用正则表达式的 Notepad++ 解决方案。在 Notepad++ 7.9.1 上测试。

查找:^(.*?\|)(ID\w\|)((?:ID\w\|)+)(.*)$。 替换为:\1\2\4\r\n\1\3\4。 选择正则表达式和环绕,不要选择点匹配换行。

反复进行全部替换,直到不再进行替换。所需的全部替换命令的数量将比行中 IDx 字符串的最大数量少 1。

查找字符串的说明:


^(.*?\|)        Group 1: Matches leading characters on the line
(ID\w\|)        Group 2: Matches the first IDx and its following |
(               Group 3 starts 
  (?:ID\w\|)+            Matches all remaining IDx's and their following |,this is a non-capturing group
)               Group 3 ends
(.*)$           Group 4: Everything on line after the last IDx and |

替换字符串输出两行。第一个具有包含第一个 IDx(组 2)的开始(组 1)和结束(组 4)文本。第二行包含围绕其他 IDx 字符串(第 3 组)的开始和结束文本。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?