【问题标题】:How to prepend a file using fish如何使用fish添加文件
【发布时间】:2020-11-16 06:04:30
【问题描述】:

我看到bash 甚至zsh(即Here)有几个很好的答案。虽然我找不到适合fish 的。

是否有规范或干净的方法将字符串或几行添加到现有文件中(就地)?类似于 cat "new text" >> test.txt 的追加操作。

【问题讨论】:

  • 你想在 文件前添加什么?
  • 在我看来,规范的 sh/bash/ksh 实现很容易采用。您在尝试这样做时是否遇到了特定问题?
  • (顺便说一句,在所有具有传统类 unix 语义的文件系统上,在文件前添加文件效率低下的警告——因此,当你不知道你的文件很短时,最好避免——将与其他任何地方一样适用于鱼类)。
  • @CJK 不起作用,因为我得到了 cat: test.txt: input file is output file 作为回报。我不想创建另一个文件,只添加相同的。
  • @Paiusco, ...btw,请注意 sponge 只是创建一个新文件并在完成后将其重命名为目标(这也是 sed -i 所做的);观察,你可以自己做。

标签: shell command-line fish prepend


【解决方案1】:

作为 fish 旨在简化的有意目标的一部分,它避免了 zsh 中的语法糖。相当于fish中的zsh-only代码<<< "to be prepended" < text.txt | sponge text.txt是:

begin; echo "to be prepended"; cat test.txt; end | sponge test.txt

sponge 是来自moreutils 包的工具; fish 版本和 zsh 原版一样需要它。但是,您可以很容易地用函数替换它;考虑以下:

# note that this requires GNU chmod, though it works if you have it installed under a
# different name (f/e, installing "coreutils" on MacOS with nixpkgs, macports, etc),
# it tries to figure that out.
function copy_file_permissions -a srcfile destfile
  if command -v coreutils &>/dev/null  # works with Nixpkgs-installed coreutils on Mac
    coreutils --coreutils-prog=chmod --reference=$srcfile -- $destfile
  else if command -v gchmod &>/dev/null  # works w/ Homebrew coreutils on Mac
    gchmod --reference=$srcfile -- $destfile
  else
    # hope that just "chmod" is the GNU version, or --reference won't work
    chmod --reference=$srcfile -- $destfile
  end
end

function mysponge -a destname
  set tempfile (mktemp -t $destname.XXXXXX)
  if test -e $destname
    copy_file_permissions $destname $tempfile
  end
  cat >$tempfile
  mv -- $tempfile $destname
end

function prependString -a stringToPrepend outputName
  begin
    echo $stringToPrepend
    cat -- $outputName
  end | mysponge $outputName
end

prependString "First Line" out.txt
prependString "No I'm First" out.txt

【讨论】:

  • 或者,您可以不使用sponge,而是写入一个临时文件,然后用它替换原始文件 - echo "to be prepended" | cat - file > temp; mv temp file
  • 是的。如果您阅读了有关该问题的 cmets,则 OP 认为基于 sponge 的 zsh 答案是他们想要复制的理想答案,这就是我走这条路的原因。
  • @CharlesDuffy 也许值得添加一个非内联解决方案,如 faho 评论作为替代方案。 (也许鱼自制功能也可以使其透明)
【解决方案2】:

对于文件大小为中小型(适合内存)的特定情况,请考虑使用ed 程序,该程序将通过将所有数据加载到内存中来避免临时文件。例如,使用以下脚本。这种方法避免了安装额外包(moreutils 等)的需要。

#! /usr/env fish
function prepend
  set t $argv[1]
  set f $argv[2]
  echo '0a\n$t\n.\nwq\n' | ed $f
end

【讨论】:

  • @CharlesDuffy 哎呀,我错过了标签。修改了答案以显示如何使用来自fish的ed
  • 你也应该把shebang改成#! /usr/bin/env fish
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 2017-10-24
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多