V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
imn1
V2EX  ›  Bash

shell/bash 有没有什么临时文件的参数或变量

  •  
  •   imn1 · 2016-10-28 19:00:09 +08:00 · 1694 次点击
    这是一个创建于 2738 天前的主题,其中的信息可能已经有所发展或是发生改变。
    好多命令是不能读取处理并输出到自身的
    command source_file > source_file 会得到一个空文件
    往往需要 copy 一份到 tmp 再读取处理输出到原来文件(覆盖)
    强迫症又要 del 这个 tmp 文件

    有没有什么参数或方法可以减少这个步骤,或减少写这个 copy

    另外有可能一个 bash 里面用不同 command 多次处理一个文件,现在比较小白,是多次 copy ……
    9 条回复    2016-10-29 23:00:14 +08:00
    invalidtoken
        1
    invalidtoken  
       2016-10-28 20:12:03 +08:00 via iPhone
    Stackoverflow 说;

    Use "sponge" from "moreutils"
    billlee
        2
    billlee  
       2016-10-28 20:15:06 +08:00
    不同 command 多次处理一个文件为什么需要 copy
    难道不是
    command_a ${INPUT} > ${OUTPUT}-a
    command_b ${INPUT} > ${OUTPUT}-b
    command_c ${INPUT} > ${OUTPUT}-c
    吗?
    debiann
        3
    debiann  
       2016-10-28 20:26:03 +08:00
    echo $(command source_file) > source_file
    jigloo
        4
    jigloo  
       2016-10-28 20:27:25 +08:00
    ceyes
        6
    ceyes  
       2016-10-29 00:32:13 +08:00 via iPhone
    有些命令如 awk 的确如此,那简单的办法就是用临时文件没问题啊,但如何利用好临时文件是可以简化的,比如:

    1. 使用 mv ,省去 cp + rm
    2. 使用 trap ,捕捉退出信号,自动删除临时文件。
    3. 把临时文件放到 /dev/shm ,之后不管也无所谓
    ETiV
        7
    ETiV  
       2016-10-29 01:31:56 +08:00
    tee ?

    command source_file | tee source_file
    imn1
        8
    imn1  
    OP
       2016-10-29 11:33:23 +08:00
    @billlee
    请理解一个新丁不会去看完所有的相关知识才去写代码的

    在目前的知识状况,例如知道一点 sed ,但不会 awk
    sed -i 直接写文件
    然后打算把换行 UNIX 格式转 WIN 格式
    网上找不到 sed 的写法,却找到 awk ,测试 OK 了,自然就想组合用,结果就是主题所述的状况
    sed 应该都可以的,但看了很多文章都没说不可视字符的写法

    为什么不学完再写,年纪大了,不像年轻时两三天就能学会写个项目,现在 bash 的那些符号我还看得很糊涂
    好汉不提当年勇咯

    一个简单需求:
    一个 utf-8/unix 换行文件(含汉字),正则替换一些内容(例如 /路径符换成 win 的\路径符),然后转为 GBK/win 格式,请教不产生临时文件的 shell 写法是

    我抽象出临时文件这个点提问,是希望知道了能用在其他命令上,不是单单为了这个需求,因为这个需求 python 两年前就搞定了
    billlee
        9
    billlee  
       2016-10-29 23:00:14 +08:00
    @imn1 效率比较高的方法是

    sed 's/\/\\/;s/$/\r/' "${inputfile}" | iconv -f utf-8 -t gbk > "${inputfile}.new"
    mv "${inputfile}.new" "${inputfile}"

    这种方法只写一遍磁盘,在同一文件系统内 mv 是不需要 copy 文件内容的。

    sed 本来就是按行流式处理,由于不存在往一个文件中间插入内容的系统调用,实际上是不可能 in-place 处理的。 sed -i 的实现也是写到一个临时文件,再 rename 回原文件。

    上面这一点很重要,像 ed/vi/nano 这些编辑器,都要把文件加载到内存后才能编辑,保存的时候就把原文件覆盖掉。所有进行流式处理的命令,是不可能直接覆盖原文件。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   984 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:57 · PVG 06:57 · LAX 15:57 · JFK 18:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.