如何用换行符替换文字 \n? (在 OS X 上)

如何用换行符替换文字 \n? (在 OS X 上)

我有一个脚本,可以从 shell 历史记录中提取一些内容并将其保存到文件中,但是如果历史记录条目中有换行符,它会以文字\n而不是换行符返回给我。我想\n在将其保存到文件之前将其替换为换行符。

我使用的是 OS X,并且认为问题可能是 OS X 附带的基于 BSD 的问题(当不正常运行sed时,这似乎总是问题!),所以我尝试了,并且在首先尝试:sedgsedsedgsed

history -1 | awk '{$1=""; print}' | gsed -e 's/^[[:space:]]*//' -e s/'\\n'/"\n"/

但如果可能的话,我想要一些可以与sedLinux 或 OS X 上的默认实用程序(无论是或其他东西)一起使用的东西,因为我不能指望gsed在 OS X 上安装,而且因为 GNUsed是正常的sed对于 Linux 来说显然不需要gsed.

答案1

sed 's/\\\\/& /g;s/\\n/\
/g;  s/\\\\ /\\\\/g' <in >out

...应该处理ewline 替换,而不会误解反斜杠转义 - 这样您仍然可以在输入中\n包含文字。不过,我对如何从历史命令中\\n获取 a 有点模糊。\n

我尝试zsh找出如何\n从历史文件中读出 ewline 而不会像这样转义:

echo '
\n'
history -1

11355 echo '\n\n'

那不行。所以,我尝试了这个:

hist(){ ! cat "$1"; }
echo '
\n'
FCEDIT=hist fc -1

echo '
\n'

...所以这可能就是你应该做的

由于某种原因,以不明确的方式zsh转义了\newlineshistoryfc -l输出,但是当它将历史命令交给某个编辑器时,它会给出真实的东西。

zsh的主要history操作方式是fc,并且该history命令只不过是 的别名fc -l。当fc使用该选项调用时-l,它将列出匹配的历史记录行到标准输出(在模糊地转义任何不可打印字符之后),但是fc的默认行为是使用一个或多个临时文件参数调用另一个实用程序,该实用程序已将其参数的所有历史匹配项写入其中。

fc从环境变量中派生它调用的实用程序的名称$FCEDIT,或者,如果未设置或为 null,则从 派生$EDITOR,或者,如果同样不成功,则默认为vi。如果调用的实用程序返回 true,则fc随后将尝试运行它在(想必)在删除临时文件之前对其进行了编辑。

因此,上述命令序列替代cat任何编辑器命令,并反转其返回值,以便成功读取 的fc临时文件将返回 false - 以防止fc再次尝试运行命令。

一个更完整的、无需调用外部实用程序的嵌入式解决方案可能如下所示:

history()
        case    $1      in
        (*/*) ! while   [ -r "$1" ]
                do      while   read -rE RTN
                        do :;   done    <$1
                shift;  done;;
        (*)     local   RTN=1  IFS=
                FCEDIT=history fc "$@"
                return  $((RTN*$?))
        esac

...它应该几乎透明地处理您可能期望zshhistory命令执行的任何参数列表;只是它的输出始终是文字,并且输出中从不包含历史时间戳或事件编号(除非你像这样称呼它history -l [args],在这种情况下它将表现为内置history

相关内容