【问题标题】:In place edit for aligning column就地编辑对齐列
【发布时间】:2020-06-22 10:12:06
【问题描述】:

我要对齐以下文件的列。

cat input.dat 
0.1     0.22474401451476203     0.22474401451476203     0.22468184471725106     0.22474401451476203     0.22474466451476202
0.15000000000000002     0.09328229408835575     0.09328229408835575     0.09323107184876382     0.09328229408835575     0.09328294408835575
0.2     0.04700471936101653     0.04700471936101653     0.04696126453738079     0.04700471936101653     0.04700536936101653
0.25    0.025562449852510022    0.025562449852510022    0.025525019904759787    0.025562449852510022    0.02556309985251002
0.30000000000000004     0.013916483625141736    0.013916483625141736    0.013883976359424946    0.013916483625141736    0.013917133625141737
0.35    0.006918972749219993    0.006918972749219993    0.0068906275518585275   0.006918972749219993    0.006919622749219994
0.4     0.0024319065284844395   0.0024319065284844395   0.002407166678723833    0.0024319065284844395   0.0024325565284844396
0.45000000000000007     -0.0005564879581991863  -0.0005564879581991863  -0.0005780476659970637  -0.0005564879581991863  -0.0005558379581991862
0.5     -0.0025717430483357794  -0.0025717430483357794  -0.0025904580222108962  -0.0025717430483357794  -0.0025710930483357794

我可以做到(和预期的输出):

cat input.dat | column -t


0.1                  0.22474401451476203     0.22474401451476203     0.22468184471725106     0.22474401451476203     0.22474466451476202
0.15000000000000002  0.09328229408835575     0.09328229408835575     0.09323107184876382     0.09328229408835575     0.09328294408835575
0.2                  0.04700471936101653     0.04700471936101653     0.04696126453738079     0.04700471936101653     0.04700536936101653
0.25                 0.025562449852510022    0.025562449852510022    0.025525019904759787    0.025562449852510022    0.02556309985251002
0.30000000000000004  0.013916483625141736    0.013916483625141736    0.013883976359424946    0.013916483625141736    0.013917133625141737
0.35                 0.006918972749219993    0.006918972749219993    0.0068906275518585275   0.006918972749219993    0.006919622749219994
0.4                  0.0024319065284844395   0.0024319065284844395   0.002407166678723833    0.0024319065284844395   0.0024325565284844396
0.45000000000000007  -0.0005564879581991863  -0.0005564879581991863  -0.0005780476659970637  -0.0005564879581991863  -0.0005558379581991862
0.5                  -0.0025717430483357794  -0.0025717430483357794  -0.0025904580222108962  -0.0025717430483357794  -0.0025710930483357794

但我正在寻找inplace 解决方案(类似于sed -i)。

当然,我可以将文件重命名为其他名称。

    cat input.dat | column -t > output.dat 
    mv output.dat input.dat

但我想知道是否有更好的解决方案。

【问题讨论】:

  • 修改后的文件应该是什么样子?
  • @Shawn 查看编辑
  • sed -i 不是真正的就地解决方案。它会在您的原始文件旁边创建一个文件,然后覆盖,就像您所做的那样。
  • 有一个moreutils 包,其中包含sponge 工具,可让您就地编辑任何内容。更多信息here。它提供的简化并不大,因此由您决定是否值得在我熟悉的任何发行版上安装一个非默认包。
  • 为什么你调用的工具创建和复制临时文件对你很重要(就像sed -iperl -iawk -i inplace 等一样)而不是你自己做(例如sed 'script' file > tmp && mv tmp file)?要求这个通常会引起“呃,为什么?”论坛上的回应,比如要求“单线”,但也许你有一个我们可以提供帮助的理由?

标签: bash awk sed sh


【解决方案1】:

就地编辑的措辞通常被误解。就地编辑意味着您不会更改磁盘上的文件。各种工具给出的大多数inplace解决方案,例如sed -iawk -i inplace,只不过是一种被掩盖的

$ tmpfile="$(mktemp)" && command file > "${tmpfile}" && mv "${tmpfile}" file

创建一个临时文件/副本,然后将其重命名为原始文件。实现不一定是这样,但会是类似的。所以你必须意识到,最终,你有可能复制数据。当在没有足够磁盘空间的大文件上操作时,这尤其麻烦。您可以通过在操作之前和之后验证文件的 inode 号来轻松检查这一点。唯一真正的 inplace 是使用 dd 完成的。

【讨论】:

    【解决方案2】:

    代替就地编辑,您可以遵循这种方法。

    $ column -t file > temp && mv temp file
    

    此函数将模拟就地格式化

    $ fip () { temp=$(mktemp) && column -t "$1" > $temp && mv $temp "$1"; }
    $ fip file
    

    【讨论】:

    • 这是我目前正在使用的解决方案。这当然给出了预期的输出,但如果可能的话,我想要inplace 解决方案,或者columnsed 等。
    • 更安全一点的可能是temp="$(mktemp)" && column -t "$1" > "$temp" && mv "$temp" "$1";
    • wrt $temp vs "$temp" - 引号不是您需要时添加的东西,而是您需要时删除的东西,请参阅mywiki.wooledge.org/Quotes。在这种情况下,您不需要删除引号,因此它们应该出现在您的变量周围。
    【解决方案3】:

    我认为改进它的唯一方法是不要无用地使用 cat。你可以简单地column -t input.dat 而不是cat input.dat | column -t,这样你就得到了

    column -t input.dat > output.dat 
    mv output.dat input.dat
    

    该命令块类似于 sed -i 所做的 (see this answer by Gilles),因此没有其他需要改进的地方。

    如果您更喜欢单行,则与命令块完全相同的是column -t input.dat > output.dat; mv output.dat input.dat。如果您只想在第一个命令成功的情况下执行第二个命令,那么 @karakfa 在他的回答中已经提供了column -t input.dat > output.dat && mv output.dat input.dat

    【讨论】:

    • 你不需要做猫。 column -t <input.dat
    • @DigvijayS 是的,我就是这么说的(你甚至不需要<)。
    • @Quasímodo, column -t input.dat 只会在屏幕上打印但不会改变input.dat 否?
    • @Boogeyman 是的,您只需在最后一个块中将 cat input.dat | column -t 替换为 column -t input.dat,但保留 > output.dat 位。
    • 好吧,cat input.dat | 部分是多余的。但即使没有它,它也是一个两行解决方案,或者正如@karakfa 提到的那样,可以将它组合成一行。但我想知道像sed -i 这样的解决方案,(不一定是column -t)。 column 似乎没有就地编辑。
    猜你喜欢
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多