【问题标题】:Windows Batch: Replace newline characters to create csv fileWindows Batch:替换换行符以创建 csv 文件
【发布时间】:2014-06-26 10:27:30
【问题描述】:

我有一个输出文件,它是一个解构的 csv 文件。

a
,b
,c
e
,f
,g
,h
i 
,j 
.......

每行的元素数量是随机的。每个元素也是随机的。我想用 ',' 替换 '\r\n,'。但我找不到这样做的语法.....

a,b,c
e,f,g,h 
i,j 
.......

我无法在服务器上安装第三方实用程序,但可以访问旧版本的 unixutils

GNU textutils 1.5
GNU sed version 3.02
GNU Awk 3.1.0

非常感谢任何帮助!

【问题讨论】:

    标签: batch-file awk sed


    【解决方案1】:

    下面的 Windows 批处理文件不需要任何第三方实用程序(包括 GNU 的):

    @echo off
    setlocal EnableDelayedExpansion
    
    set "out="
    for /F "delims=" %%a in (file.txt) do (
       set "in=%%a"
       if "!in:~0,1!" neq "," (
          if defined out echo !out!
          set "out=!in!"
       ) else (
          set "out=!out!!in!"
       )
    )
    echo !out!
    

    如果行包含感叹号,此程序将失败。这一点可能是固定的。

    【讨论】:

    • +1。人们再也看不到高质量的批处理编程了。
    【解决方案2】:

    另一个sed 选项:

    $ sed -ne '/^,/H;/^[^,]/{;x;s/\r\n//g;/./p;};${;x;s/\r\n//g;p;}' input
    a,b,c
    e,f,g,h
    i,j
    

    为了更容易阅读,下面是这个的工作原理:

    • /^,/H; -- 对于任何以逗号开头的行,将其附加到 sed 的“hold”。
    • /^[^,]/{ -- 对于任何以逗号开头的行(这意味着我们位于前一组输入行的末尾):
      • x; -- 交换模式并保留空格(因此下一行的开头在保留中),
      • s/\r\n//g; -- 删除模式中的所有换行符,
      • /./p;}; -- 如果这里确实有模式(即不是空行),请打印出来。
    • ${x;s/\r\n//g;p} -- 然后在文件末尾做同样的事情。

    请注意,这应该适用于非 GNU sed 以及 GNU。我在 FreeBSD 和 OSX 中对其进行了测试,尽管使用的是 unix 风格的行尾,然后将 \r 添加到了这个答案的替换中。 YMMV。

    【讨论】:

      【解决方案3】:

      这是awk 版本

      awk 'NR>1 {printf "%s"($0~/^,/?"":RS),a} {a=$0} END {print $0}' file
      a,b,c
      e,f,g,h
      i ,j
      

      您的输入文件中i 后面有一个空格,它没有被删除。如果您想删除它,请执行以下操作:

      awk 'NR>1 {printf "%s"($0~/^,/?"":RS),a} {sub(/ +$/,"");a=$0} END {print $0}' file
      a,b,c
      e,f,g,h
      i,j
      

      【讨论】:

      【解决方案4】:

      我用 awk 得到了这个:

      awk '/,/{x=x$0;next} {if(length(x))print x;x=$0}' file
      

      如果该行有逗号,则将此行添加到变量x。如果没有,则打印x(如果其中有任何内容)并使用当前行开始一个新的x

      【讨论】:

      • 这不会打印最后一行,因为 print 不再被调用,因为没有,的行没有@
      【解决方案5】:

      只需适当设置输入记录分隔符和输出记录分隔符:

      awk -v RS='\r\n,' -v ORS=',' '1' file
      

      或者读入整个文件并进行全局替换:

      awk -v RS='^$' '{gsub(/\r\n,/,",")}1' file
      

      根据您运行的平台,您可能需要添加 -v BINMODE=3 以阻止 C 实用程序在 awk 有机会解析它之前剥离 \r

      【讨论】:

        【解决方案6】:

        你也可以使用 sed

        sed  ':loop ; N ;s/\n//g ; s/\(\w\)\(\w\)/\1\n\2/g ; t loop ' file_name
        

        【讨论】:

          【解决方案7】:

          另一种 awk 方式

          awk '/,/{x=x$0}!/,/{if(x)print x;x=$0}END{print x}' file
          

          还有一个没有空格

          awk '/,/{x=x$0}!/,/{x?x=x"\n"$0:x=$0}END{gsub(/ /,"",x);print x}' file
          

          【讨论】:

            猜你喜欢
            • 2020-06-07
            • 1970-01-01
            • 2015-08-18
            • 1970-01-01
            • 2012-12-12
            • 2014-07-04
            • 2021-11-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多