【问题标题】:In Bash, how do I add a string after each line in a file?在 Bash 中,如何在文件的每一行之后添加一个字符串?
【发布时间】:2011-02-21 14:48:40
【问题描述】:

如何使用 bash 在文件的每一行之后添加一个字符串?可以用sed命令完成吗,如果可以怎么办?

【问题讨论】:

    标签: linux bash unix sed


    【解决方案1】:

    如果您的sed 允许通过-i 参数进行就地编辑:

    sed -e 's/$/string after each line/' -i filename
    

    如果没有,你必须制作一个临时文件:

    typeset TMP_FILE=$( mktemp )
    
    touch "${TMP_FILE}"
    cp -p filename "${TMP_FILE}"
    sed -e 's/$/string after each line/' "${TMP_FILE}" > filename
    

    【讨论】:

    • 你为什么touch临时文件?我会让sed 命令以cp 的成功为条件,否则原始命令可能会丢失。
    • 我触动了文件快速保留临时名称。这可能不需要。我认为您将 sed 命令作为 cp 成功的条件是正确的。为什么不编辑代码来进行修复。我一点都不介意!你的,汤姆
    • @Oxwivi: sed -e 's/^/string after each line/' -i filename $ 表示行尾。 ^ 表示行首。
    • 您能否解释一下 $ 符号在您的答案中的作用?如果您了解正在发生的事情,答案会更有帮助。
    • @shuhalo 根据 gnu sed 文档$ also acts as a special character only at the end of the regular expression。所以$ 正则表达式抓取每行的结尾,s/$/appendix/ 用给定的字符串替换行的结尾。这是我的理解。
    【解决方案2】:

    我更喜欢使用awk。 如果只有一列,请使用$0,否则替换为最后一列。

    一种方式,

    awk '{print $0, "string to append after each line"}' file > new_file
    

    或者这个,

    awk '$0=$0"string to append after each line"' file > new_file
    

    【讨论】:

    • 另外,要附加行号(在我的情况下),可以使用NR 变量:awk '{print $0, NR}'
    • @optimus 我试过你的方法,但是得到了额外的空间,知道如何删除它们吗?
    • @AdilSaju sed 's/ //g' 这符合我的要求,但它会删除每一行中的空格,这就是 g 用于一行中任何地方的选项。
    • @AdilSaju 请添加详细信息。最好提出一个新问题。
    • @AdilSaju awk 删除 , 喜欢 {print $0"string to append after each line"}
    【解决方案3】:

    我更喜欢echo。使用纯 bash:

    cat file | while read line; do echo ${line}$string; done
    

    【讨论】:

    • 这是一个很好的解决方案,它可以与ls 的输出一起使用(或任何产生多行输出的东西)。
    • 先给字符串变量加值,比如string=0
    【解决方案4】:

    如果你有它,lam(层压)实用程序可以做到,例如:

    $ lam filename -s "string after each line"
    

    【讨论】:

      【解决方案5】:
      1. POSIX shellsponge:

        suffix=foobar
        while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
        sponge file
        
      2. xargsprintf

        suffix=foobar
        xargs -L 1 printf "%s${suffix}\n" < file | sponge file
        
      3. 使用join

        suffix=foobar
        join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
        
      4. Shell 工具使用pasteyeshead &wc:

        suffix=foobar
        paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file
        

        注意paste$suffix 之前插入了一个Tab 字符。

      当然sponge 可以替换为临时文件,然后mv'd 覆盖原始文件名,就像其他一些答案一样......

      【讨论】:

      • 这些都不比sed更可取,除非资源非常有限。
      • 我喜欢非 sed 解决方案。这么简单的工作不需要sed
      【解决方案6】:

      这只是添加使用 echo 命令在文件中每一行的末尾添加一个字符串:

      cat input-file | while read line; do echo ${line}$"string to add" >> output-file; done
      

      添加 >> 会将我们所做的更改定向到输出文件。

      【讨论】:

        【解决方案7】:

        Sed 有点丑,你可以优雅地这样做:

        hendry@i7 tmp$ cat foo 
        bar
        candy
        car
        hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
        barbar
        candybar
        carbar
        

        【讨论】:

        • 对于行数超过 shell 最大参数限制的文件失败。试试:cat foo |一边读一边读;做回声 ${a}bar ;完成或类似的事情;在大多数情况下,它是 for 的合适替代品。
        • 对于带有空格的行也会失败。
        • 呃,不,丹尼斯不会失败。 shell的最大参数限制? Crikey,你是悬而未决的。
        • 是的:$ cat foo foo bar baz alex@armitage:~$ for i in cat foo;回声 ${i}bar;完成了 foobar barbar bazbar 但经过一些测试,我的推理可能是错误的,但丹尼斯是对的
        • @hendry 是的,对于其中包含空格的行,这确实会失败,例如 echo "foo bar" | (for i in `cat`; do echo ${i}bar; done) 即使输入是 1 行 foo bar 也会打印 2 行(和 cat 从标准输入读取而不是文件对此没有任何影响)。
        猜你喜欢
        • 2015-02-26
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多