如何复制一行并使用 sed 搜索和替换重复行?

Fre*_*Tep 8 sed text-processing

我试图复制文本文件中包含某些特殊字符的行,但在副本中,用“常规”ASCII 字符替换特殊字符。具体用例是重音字符。

\n

输入:

\n
\xc3\xa9va\ntest\nfr\xc3\xa9d\xc3\xa9ric\n
Run Code Online (Sandbox Code Playgroud)\n

期望的输出:

\n
\xc3\xa9va\neva\ntest\nfr\xc3\xa9d\xc3\xa9ric\nfrederic\n
Run Code Online (Sandbox Code Playgroud)\n

现在我可以复制包含该字符的行\xc3\xa9,但我不确定如何在捕获组中搜索和替换。

\n

这是我到目前为止所得到的:

\n
echo '\xc3\xa9va\\ntest\\nfr\xc3\xa9d\xc3\xa9ric' | sed 's/\\(.*\xc3\xa9.*\\)/&\\n\\1/'\n
Run Code Online (Sandbox Code Playgroud)\n

我可以这样做吗sedawk如果没有的话,我很乐意与...合作

\n

Ste*_*itt 14

您可以匹配\xc3\xa9然后应用多个命令:

\n
sed '/\xc3\xa9/{p;s/\xc3\xa9/e/g;}'\n
Run Code Online (Sandbox Code Playgroud)\n

对于任何包含 的行\xc3\xa9,这将打印当前模式空间,然后将所有\xc3\xa9s 替换为e(并再次打印模式空间)。

\n

AWK 等效项是

\n
awk '/\xc3\xa9/{print; gsub(/\xc3\xa9/, "e")}1'\n
Run Code Online (Sandbox Code Playgroud)\n

sed\xe2\x80\x99ss命令可以重用地址模式:

\n
sed '/\xc3\xa9/{p;s//e/g;}'\n
Run Code Online (Sandbox Code Playgroud)\n

如果你的替换都是单字符替换,那么该y命令会更有效:

\n
sed '/\xc3\xa9/{p;y/\xc3\xa9/e/;}'\n
Run Code Online (Sandbox Code Playgroud)\n

  • @schrodigerscatcuriosity 结果是相同的,理论上可能存在性能差异(您的方法在所有行中匹配“é”两次)。 (2认同)
  • @schrodigerscatcuriosity 是的,这是边缘的;对这两种方法进行分析显示,您的变体中的 CPU 指令增加了约 9.4%(但周期仅增加了约 3.6%),Haswell 上的分支增加了约 6.4%,分支未命中增加了约 4.5%。我使用了 `/usr/share/dict/french`,一个 346,200 行的文件,生成 454,926 行输出。 (2认同)

Ed *_*ton 11

$ awk '1; gsub(/\xc3\xa9/,"e")' file\n\xc3\xa9va\neva\ntest\nfr\xc3\xa9d\xc3\xa9ric\nfrederic\n
Run Code Online (Sandbox Code Playgroud)\n

以上使用:

\n
    \n
  1. 1使 awk 执行打印当前行的默认操作的惯用 true 条件,然后:
  2. \n
  3. gsub()\xc3\xa9用s替换任何es,如果找到/替换了任何\xc3\xa9s,那么在条件上下文中使用的正返回会再次导致 awk 执行打印当前(现在已修改)行的默认操作。
  4. \n
\n

请注意,通过使用返回码 fromgsub()来告诉我们是否找到了任何s,它使我们不必在命令中\xc3\xa9重复指定相同的正则表达式。/\xc3\xa9/

\n


row*_*oat 6

另一种sed选择 - 受到@EdMorton\'sawk答案的启发

\n
sed -n \'p;s/\xc3\xa9/e/gp\' file\n
Run Code Online (Sandbox Code Playgroud)\n


sch*_*ity 5

另一种选择,类似于@Stephen Kitt\'s

\n
$ sed \'/\xc3\xa9/p;s/\xc3\xa9/e/g\'\n\xc3\xa9va\neva\ntest\nfr\xc3\xa9d\xc3\xa9ric\nfrederic\n
Run Code Online (Sandbox Code Playgroud)\n
\n
    \n
  • /\xc3\xa9/p选择有字符的行\xc3\xa9并打印。
  • \n
  • s/\xc3\xa9/e/g打印前面的行并进行替换。
  • \n
\n