【问题标题】:adding character at the end of each string in a file在文件中每个字符串的末尾添加字符
【发布时间】:2017-04-10 09:11:27
【问题描述】:

我有一个 txt 文件,其中包含单个单词的单列:

windfall
winnable
winner
winners
winning

我想将文件中的单词用作映射作业的正则表达式字符串。完成后,单词应如下所示:

windfall|winnable|winner|winners|winning

我需要用python或者awk打开文件,放一个|在每个末尾,并将新内容写入一个新文件,并添加新字符并将列转换为单个水平线。

有什么建议吗?

【问题讨论】:

  • 是的,不要那样做。这是XY Problem,请向我们寻求帮助,以解决您想要做的事情而不是您想做的事情。

标签: python file awk


【解决方案1】:

最简单的是tr:

tr '\n' '|' < file.txt

【讨论】:

  • 这将添加一个尾随 | 并且末尾没有换行符...改用 paste -sd'|' file.txt
  • @Sundeep 这就是为什么我没有发布但问题的标题是在每个字符串的末尾添加字符,强调每个 ,
  • @JamesBrown 可能难以用语言表达.. 预期输出足够清晰
【解决方案2】:

使用 Python 你可以做到:

with open('oldfile.txt') as fin:
    with open('newfile.txt', 'w') as fout:
        fout.write('|'.join(map(str.strip, fin)))

str.split 删除换行符和空格,而join 将行与| 连接。

【讨论】:

    【解决方案3】:

    使用sed

    $ cat file
    windfall
    winnable
    winner
    winners
    winning
    $ sed ':a;N;s/\n/|/;ba' file
    windfall|winnable|winner|winners|winning
    
    • 使用:a 创建循环
    • 将新行N 加载到执行空间中
    • 用管道替换换行符
    • 冲洗并重复。

    【讨论】:

      【解决方案4】:

      在 awk 中,如果你不想要结尾的 |

      $ awk '{ s=s (NR>1"?"|":"") $0 } END { print s }' file
      windfall|winnable|winner|winners|winning
      

      带有getline 的原始版本基本上是(甚至不是)awk 干扰会话的结果:

      $ awk 'BEGIN {
                 while(r=getline) {         # read until EOF
                     s=s (p==r?"|":"") $0;  # pile it to s, preceed with | after the first
                     p=r                    # p revious r eturn value of getline
                 } print s                  # out with the pile
             }' file
      windfall|winnable|winner|winners|winning
      

      【讨论】:

      • 这将在 getline 失败时进入无限循环。请参阅awk.freeshell.org/AllAboutGetline,了解如何以及何时使用 getline 及其许多注意事项。
      • @EdMorton 什么样的情况或者getline失败会导致死循环?我(再次)通过该链接阅读,但无法快速设计出会导致这种情况的方案。我在提到的文本中看到的唯一getline 失败是 在符合 POSIX 的 awks(例如 gawk --posix)中,getline 失败(例如尝试从不可读的文件中读取)对程序来说是致命的,否则不会。我对其进行了一些测试,在chmod a-r file 之后,两个版本(有和没有getline)都失败了fatally,getline 版本和--posix 在尝试处理目录时也是如此。
      • Per POSIX All forms of getline shall return 1 for successful input, zero for end-of-file, and -1 for an error. 因此在这种情况下,您将 r 设置为 -1 并进入循环,然后下一次迭代 getline 将再次失败,依此类推。如果你要求一个特定的测试用例,我只是对调用进行健壮的编码(它只是几个额外的字符),所以如果它发生,它会处理这个问题,因为每个 POSIX 它可能会发生,然后我没有担心它是如何发生的,或者当它发生时哪些 awks 会产生特定的失败。
      • @EdMorton 好的,谢谢,先生。顺便说一句,这里不是想开始争论,只是想学习但也不能想当然;我是那些只需要触碰火焰才能相信的人之一。此外,不是getline 的真正朋友,但时不时地访问黑暗面似乎很有趣。 echo itsme &gt; foo; chmod a-r foo; awk --posix '{print getline}' foo(和其他一些)似乎在 print 实际输出任何东西之前失败了。
      • 没问题。但请记住,仅仅因为您使用 --posix 运行 gawk 并不能保证其他 POSIX awk 的行为不会有所不同。 POSIX 没有定义一些行为(例如,如何处理 print &gt; "foo" "bar"),因此任何 awk 都可以对它们做任何事情,并且仍然符合 POSIX。
      【解决方案5】:
      awk -v RS= -v OFS="|" '/ /{next}$1=$1' file
      
      windfall|winnable|winner|winners|winning
      

      【讨论】:

        【解决方案6】:

        使用paste:

        $ cat /tmp/so.txt
        windfall
        winnable
        winner
        winners
        winning
        
        $ paste -sd'|' /tmp/so.txt
        windfall|winnable|winner|winners|winning
        

        【讨论】:

          猜你喜欢
          • 2016-07-20
          • 2011-09-16
          • 1970-01-01
          • 1970-01-01
          • 2021-10-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多