【问题标题】:Remove LF from the last line in file从文件的最后一行删除 LF
【发布时间】:2012-03-31 23:41:25
【问题描述】:

我文件的最后一行不应将 LF 作为最后一个字符。

在vim中我可以做到

:set noendofline binary
:wq

http://vim.wikia.com/wiki/File_format#Terminator_after_last_line

如何使用 sed oneliner 过滤器来实现更长的管道?

任何其他工具(无头 vim?awk)对我来说都可以。请不要perl。

scala 或 haskell 怎么样!?

【问题讨论】:

  • 这是什么文件?文本,二进制?它是如何创建的?它是文件中唯一的 LF 吗?
  • 这有关系吗?只需删除最后一个 LF。假设是二进制,其实是xml文本。
  • 事实上,我想去掉一些 xml 的开头和结尾标记周围的所有空格(包括 LF)。
  • sed 在行上工作(某些版本的sed 对这些行的长度有限制);行以 LF 结尾,包括文件中的最后一行。我认为您不会发现sed 是完成这项工作的正确工具。因为我会使用 Perl,所以我帮不上忙,尽管您可能可以使用 Python。
  • 对我的 perl 评论感到抱歉 :-) 但是这种语言已经过时了,我不想再学习了...

标签: scala vim haskell sed awk


【解决方案1】:

如果您想丢失所有换行符,可以使用以下方法:

awk '{printf "%s", $0}'

您也可以使用tr -d '\012' 删除LF (NL) 字符;对于这项工作,它可能比 awk 快。

使用更精细的awk 脚本,您可以保留除最后一个换行符之外的所有换行符,如果这是您想要的:

awk '{if (NR>1) print old; old=$0;} END { printf "%s", old }'

tr 不能这样做!)这两个awk 脚​​本都可以插入到管道中。我不知道awk 是否会处理巨大的“单行”文件,但它可能会处理它们。请记住,许多 Unix 工具都是基于线条的——小心不要把它们推得太紧,并在投入生产之前仔细测试。

【讨论】:

  • 一个稍微不同的写法是awk -v old="" 'NR>1 { print old; old=$0 } END { printf "%s", old }'
【解决方案2】:

您可以使用head 获取除最后一个以外的所有字节:

head -c $(($(stat -c %s file.txt)-1)) file.txt

python:

python -c 'import sys; sys.stdout.write(sys.stdin.read()[:-1])' <file.txt

【讨论】:

  • 越来越近:如何在管道中使用它?对 fname 的引用不好......
  • @Bastl, xargs 可以带你到那里,即使是一件物品:echo file.txt | xargs -I FILE bash -c 'head -c $(( $(stat -c %s FILE) - 1 )) FILE'
【解决方案3】:

这并不像看起来那么简单。你可以使用这个 awk(1) 过滤器:

awk ' { if(l) { print line; } line=$0; l=1; } END { if(l) printf("%s", line); }'

简而言之:它逐行读取。如果已经读取了一行(= l 为真),则打印它并记住下一行。最后,不换行打印最后一行。

您可以使用 sed(1) 实现相同的效果,您可以将输入视为单行,但我找不到执行此操作的选项。

【讨论】:

    【解决方案4】:

    由于您特别要求 Haskell 版本,这里有一个使用 ByteStrings 的版本,在标准输入和标准输出上运行:

    import Data.ByteString as B
    import Data.ByteString.Internal (c2w)
    import Data.Word
    
    main :: IO ()
    main = B.interact removeLastLF
    
    lf :: Word8
    lf = c2w '\n'
    
    removeLastLF :: ByteString -> ByteString
    removeLastLF xs | B.last xs == lf = B.init xs
                    | otherwise       = xs
    

    【讨论】:

      【解决方案5】:

      我认为这可以在 Haskell 中解决问题:

      import Data.List (intercalate)
      main = interact (intercalate "\n" . lines)
      

      【讨论】:

      • 什么?为什么?那可以添加换行符,但不能删除。你的意思是打电话给init
      【解决方案6】:

      你可以通过 tr 简单地 cat:

      cat filename | tr -d "\n" > filename.nonl
      

      【讨论】:

      • 这将删除所有行,我只想要最后一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2011-06-20
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      • 2012-07-23
      • 1970-01-01
      相关资源
      最近更新 更多