【问题标题】:Line Breaks in Unix File [duplicate]Unix文件中的换行符[重复]
【发布时间】:2016-10-27 09:08:36
【问题描述】:

我有一个文件,其中的记录由 | 分隔。有几个换行符,第一行的一部分移动到第二行。如果我计算 |在特定的行中,它应该始终保持一致。如何识别哪一行有换行符并将两行附加到一行中以作为“|”的数量每一行都是一致的?

文件如下所示:

DeptID|EmpFName|EmpLName|Salary
Engg|Sam|Le
wis|1000
Engg|Smith|Davis|2000
HR|Denis
|Lillie|1500
HR|Danny|Borr
inson|3000
IT|David|Letterman|2000
IT|John|Newman|3000

而我想计算 '|' 的数量在每一行。

在这种情况下,每行应该有 3 个 '|'每个,但由于换行,情况并非如此,

我最终想要的输出是

DeptID|EmpFName|EmpLName|Salary
Engg|Sam|Lewis|1000
Engg|Smith|Davis|2000
HR|Denis|Lillie|1500
HR|Danny|Borrinson|3000
IT|David|Letterman|2000
IT|John|Newman|3000

【问题讨论】:

  • 请发布一些示例数据和预期输出。
  • 重复问题中的答案除了添加空间外有效......所以需要进行一些修改,我不知道更改是否微不足道(不是指字段分隔符,而是额外的空间)
  • 你不能使用sed 用空字符串替换换行符吗?我的意思是,首先你使用 'awk' 来知道 | 字符的数量,如果它小于 3,你用一个空字符串删除换行符。
  • @Dominique,是的,我在 sed 中实现了你的想法,很简单,因为最大拆分是跨两行...

标签: linux file awk sed


【解决方案1】:

awk 中的一个:

$ cat foo.awk
BEGIN { FS=OFS="|" }  # set separators
NR==1 { nf=NF }       # expect the field count to be correct on header record
NF<nf {               # if NF less than on header record
    while (NF<nf) {   # and while NF < less than on header record
        b=$0          # buffer too short record
        getline       # read next record
        $0 = b $0     # catenate buffer and fresh record
    }
} 1                   # output

运行它:

$ awk -f foo.awk foo
DeptID|EmpFName|EmpLName|Salary
Engg|Sam|Lewis|1000
Engg|Smith|Davis|2000
HR|Denis|Lillie|1500
HR|Danny|Borrinson|3000
IT|David|Letterman|2000
IT|John|Newman|3000

不检查记录是否过长。

【讨论】:

    【解决方案2】:

    鉴于如相关 OP 所述,拆分最多跨越两行,sed 可用于简单的解决方案

    $ cat ip.txt 
    DeptID|EmpFName|EmpLName|Salary
    Engg|Sam|Le
    wis|1000
    Engg|Smith|Davis|2000
    HR|Denis
    |Lillie|1500
    HR|Danny|Borr
    inson|3000
    IT|David|Letterman|2000
    IT|John|Newman|3000
    
    $ sed '/.*|.*|.*|/! {N; s/\n//}' ip.txt 
    DeptID|EmpFName|EmpLName|Salary
    Engg|Sam|Lewis|1000
    Engg|Smith|Davis|2000
    HR|Denis|Lillie|1500
    HR|Danny|Borrinson|3000
    IT|David|Letterman|2000
    IT|John|Newman|3000
    
    • /.*|.*|.*|/! 如果行不包含三个 |
      • {N; s/\n//} 获取下一行并首先删除 \n


    使用分组和量词来指定一个数字

    sed '/\(.*|\)\{3\}/! {N; s/\n//}' ip.txt
    

    使用扩展正则表达式,-E-r

    sed -E '/(.*\|){3}/! {N; s/\n//}' ip.txt
    

    【讨论】:

    • 有没有办法将值 3 存储在一个变量中,并在上面的命令中使用该变量。我正在尝试使用以下内容,但它不接受变量值.. $ cat ip.txt Deptme|EmpLName|Salary Engg|Sam|Le wis|1000 Engg|Smith|Davis|2000 HR|Denis |Lillie|1500 HR |Danny|Borr inson|3000 IT|David|Letterman|2000 IT|John|Newman|3000 $ var=$(sed 's/[^|]//g' ip.txt | awk '{ print length }' |头 -1) $ echo $var 2 $ sed '/(.*|)\{${var}\}/! {N; s/\n//}' ip.txt sed: -e expression #1, char 19: Invalid content of \{\}
    • 使用sed "/\(.*|\)\{$var\}/! {N; s/\n//}" ip.txt
    猜你喜欢
    • 2015-02-18
    • 2018-03-06
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 2021-04-18
    • 2012-11-19
    • 2021-10-25
    • 2021-08-10
    相关资源
    最近更新 更多