linux - 从管道分隔文件中的字段查找和替换管道分隔符

标签 linux shell unix awk sed

我早些时候遇到过类似的问题,后来我不得不为该问题添加更多范围,但不知道如何编辑它并使其再次生效。这就是我发布新问题的原因。

我的文件是竖线分隔文件。

 NAME | NUM | WEB | LOCATION | CURRENCY | PLACE
 ABCD | 04  | GO|OGLE | EUROPE | EURO   | PARIS
 XYZE | 12  | Y|A|HOO | USA    | DOLLAR | SEATTLE
 LMNO | 17  | |FACE|B|O|O|K | ASIA | ASIAN DOLLAR | HONGKONG
 EDDE | 98  | A||M|AZ|ON| | AFRICA | AF DOLLAR | CAPETOWN

我的文件就这么复杂。我们需要的是去掉“|”来自 WEB 字段的符号,并将其替换为#、$、& 或任何垃圾值。

输出必须是:

NAME | NUM | WEB | LOCATION | CURRENCY | PLACE
ABCD | 04  | GO#OGLE | EUROPE | EURO   | PARIS
XYZE | 12  | Y#A#HOO | USA    | DOLLAR | SEATTLE
LMNO | 17  | #FACE#B#O#O#K | ASIA | ASIAN DOLLAR | HONGKONG
EDDE | 98  | A##M#AZ#ON# | AFRICA | AF DOLLAR | CAPETOWN

我试过 awk'ing 几个过滤器来清除这个困惑。似乎没有什么能找到圆满的结局。谢谢你! 我要感谢几个回答我上一个问题的名字:RomanPerekhrest、Ed Morton、shellter、val rog。

最佳答案

$ cat tst.awk
BEGIN { FS=OFS="|" }
NR==1 { outNf=NF; print; next }
{
    end = beg + (NF - outNf) - 1
    for (i=1; i<=NF; i++) {
        sep = (i>=beg && i<=end ? "#" : OFS)
        printf "%s%s", $i, (i<NF ? sep : ORS)
    }
}

$ awk -v beg=3 -f tst.awk file
 NAME | NUM | WEB | LOCATION | CURRENCY | PLACE
 ABCD | 04  | GO#OGLE | EUROPE | EURO   | PARIS
 XYZE | 12  | Y#A#HOO | USA    | DOLLAR | SEATTLE
 LMNO | 17  | #FACE#B#O#O#K | ASIA | ASIAN DOLLAR | HONGKONG
 EDDE | 98  | A##M#AZ#ON# | AFRICA | AF DOLLAR | CAPETOWN

工作原理:在第一行,要输出的字段数与该行的字段数相同,因此将该数字保存为 outNF。从那时起,任何包含超过 outNF 字段的后续行都有从 beg 开始的 outNF-NF 字段进行组合。所以在循环内部,它在从 1 到 beg 的字段之间使用 OFS,然后从 beg+1 到 beg+(outNF-NF) 它在字段之间使用 # 从该范围内的输入字段创建一个合并的输出字段,然后返回到在字段之间使用 OFS。

关于linux - 从管道分隔文件中的字段查找和替换管道分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45980204/

相关文章:

java - 'yum install java-1.8.0' 是某种别名吗?

linux - 用于运行和测试 ssh 命令的 Unix 编辑器

linux - 使用父目录和祖父目录重命名文件

linux - Ghostscript 故障安全机制?

ruby - 在 linux 上的 ruby​​ 中,有没有办法获取捕获信号的 siginfo_t 数据?

javascript - 如何使用 Electron 应用程序关闭文件

linux - SSH断线后执行shell脚本最后几行

linux - 关于回车

linux - 获取星期一和星期日等一周的任何日期作为 Unix 中的参数

linux - (unix/bash) 使用 ">>"与终端的详细信息?