【问题标题】:How to use sed to substitute LF with space, but not CRLF?如何使用 sed 用空格代替 LF,而不是 CRLF?
【发布时间】:2018-06-07 09:02:11
【问题描述】:

我有一个 csv 文件,它混合了 CRLFLF。在某些时候有一个 LF,实际上内容属于之前的行。

例子:

smith;pete;he is very nice;1990CRLF
brown;mark;he is very nice;2010CRLF
taylor;sam;he isLF
very nice;2009CRLF

在我的脚本中,我想删除 LF 的所有独立实例。 我尝试使用 sed:

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' $my_file

此解决方案的问题在于,属于 CRLFLF 也被替换为空格字符。

【问题讨论】:

标签: bash shell sed


【解决方案1】:

perl 默认情况下不会删除记录分隔符,因此可以轻松操作

$ cat -A ip.txt
smith;pete;he is very nice;1990^M$
brown;mark;he is very nice;2010^M$
taylor;sam;he is$
very nice;2009^M$

$ perl -pe 's/(?<!\r)\n/ /' ip.txt
smith;pete;he is very nice;1990
brown;mark;he is very nice;2010
taylor;sam;he is very nice;2009

$ perl -pe 's/(?<!\r)\n/ /' ip.txt | cat -A
smith;pete;he is very nice;1990^M$
brown;mark;he is very nice;2010^M$
taylor;sam;he is very nice;2009^M$

(?&lt;!\r)\n 使用否定后视来确保我们仅在 \n 前面没有 \r 时才替换它


修改 OP 的尝试:

$ sed -e ':a' -e 'N' -e '$!ba' -e 's/\([^\r]\)\n/\1 /g' ip.txt
smith;pete;he is very nice;1990
brown;mark;he is very nice;2010
taylor;sam;he is very nice;2009

\([^\r]\) 确保\n 前面的字符不是\r

【讨论】:

    【解决方案2】:

    使用 awk:

    $ awk 'BEGIN{RS=ORS="\r\n"}/\n/{sub(/\n/,"")}1' file
    smith;pete;he is very nice;1990
    brown;mark;he is very nice;2010
    taylor;sam;he isvery nice;2009
    

    解释:

    $ awk '
    BEGIN { RS=ORS="\r\n" }  # set the record separators to CRLF
    /\n/ {                   # if there is stray LF in the record
        sub(/\n/,"")         # remove it (maybe " " to replace it with a space)
    }1' file                 # output it
    

    在 gawk、mawk 和 Busybox awk 上成功测试。 BSD awk 失败,例如:

    awk '!/\r$/{printf "%s",$0;next}1' file
    

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      相关资源
      最近更新 更多