【问题标题】:How to convert 1st 4 spaces in a file to tab如何将文件中的前 4 个空格转换为制表符
【发布时间】:2018-12-11 07:48:26
【问题描述】:

我的文件 abc.txt 在某些行上有空格。有些行有 4 个空格,而有些行有 4 个以上的空格。我想将第一个 4 个空格转换为一个选项卡,留下其余的空格。我试过了

unexpand -t 4 --first-only abc.txt > efg.txt 以及一些 sed 等价物。他们将我所有的空格都转换为制表符,但不仅是第一次出现的 4 个空格序列。这在 shell 和 ruby​​ 中如何实现?

【问题讨论】:

  • 你能显示你的输入和输出文件吗,对我来说没有任何问题

标签: bash shell


【解决方案1】:

您可以使用sed 轻松做到这一点:

sed "s/^    /$(printf '\t')/g" abc.txt > efg.txt

要详细了解为什么需要$(printf '\t'),请查看this answer。正如另一个答案中所述并在 cmets 中详细讨论,这种模式也可以表示为:

sed "s/^ \{4\}/$(printf '\t')/g" abc.txt > efg.txt

根据您的偏好,您可能会发现其中一个或多或少明确且易于理解。

【讨论】:

  • 这行得通,但它创建了一个 8 个空格而不是 4 个空格。
  • 标签就是标签。它的显示方式与您正在查看的程序的配置有关。大多数程序默认使用8 的制表位。您使用哪个程序查看文件?
  • 对于上下文,这是在 bash 中设置 4 制表位的方法:stackoverflow.com/questions/10782699/… 或在 vi 中:stackoverflow.com/questions/1878974/redefine-tab-as-4-spaces
  • 如果文件不是很大并且想要就地进行更改,可以在这里使用sponge (moreutils)。
  • 海绵很干净!您也可以使用 -i 选项对 sed 进行内联更改。我认为这不是必需的/不可取的,因为 OP 列出了不同的输入/输出文件。一般来说,-i sed 选项被看不起,取而代之的是:sed s'/find/replace' in.txt > in.txt.tmp && mv in.txt.tmp in.txt ... 这是一个非常标准的用于幂等替换文件的 shell 习惯用法。
【解决方案2】:

在红宝石中:

'/path/to/file'.tap do |file|
  File.write(file, File.read(file).gsub(/^ {4}/, "\t"))
end

为避免将整个文件加载到内存中,请改用File#readline

【讨论】:

  • 这看起来像是将整个文件读入内存,subs,然后将整个文件写回磁盘而不是逐行操作?此外,我发现 `{4}` 模式很有趣,因为四个文字空格和模式 `{4}` 正好是四个空格宽。
  • @MatthewStory 是的,这不是最有效的版本,在现实生活中,我会选择sed如果文件的大小非常大。跨度>
  • 我也宁愿被告知“这是 4 个空格(即 `{4}`),即使它的字符长度相同,也不必计算并计算出有多少空格我自己的......并明确表示“是的,我打算 4 个空格”,而不是“我的猫坐在我的空格键上,我们最终得到 4 个”......而且,如果他们决定他们想要,更容易改变6个空格或其他什么。
  • @SimpleLime 是的......我可以选择任何一种方式。我也考虑在我的解决方案中使用 `{4}`,只是觉得它们的长度相同很有趣。绝对不是批评在四个文字空间上使用这种风格,只是分享一个观察。
  • 啊,是的,在我最初的阅读中,我读到你对它的评论更像是对这样做的被动攻击性攻击,我进入了辩论模式,甚至在 5 分钟后重新阅读,它绝对没有我想象的那么被动攻击。
猜你喜欢
  • 2011-08-10
  • 2012-06-21
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
相关资源
最近更新 更多