【问题标题】:Replace some but not all spaces in text file (shell/bash)替换文本文件中的一些但不是全部空格(shell/bash)
【发布时间】:2016-06-30 08:55:39
【问题描述】:

假设我有一个具有下一个结构的文件(example.txt):

NAAME 111 2222 333
NAMME 111 22 333 
NNA ME 444 555 2
NNAAME 1 5 8
N MEEE 44 66 111

我想用分隔符替换数字之间的空格,例如 |, 但不影响名称。

我正在考虑的一个选项是更改名称中的空格并放置一个“低杠”,然后删除文件中的所有空格并写上“|”并再次将名称中的“_”更改为空格。

知道如何在 shell 中做到这一点吗?或者也许是更好的选择?

预期的输出是这样的

NAAME|111|2222|333
NAMME|111|22|333 
NNA ME|444|555|2
NNAAME|1|5|8
N MEEE|44|66|111

非常感谢!

【问题讨论】:

  • 我已经更新了
  • 您正在显示预期的输出,名称后的所有空格都替换为管道 | 和我在整个线程中看到的唯一 code重新说你想要的是andlrc写的。克里斯·梅斯(Chris Maes)和您作为对他的回答的评论所写的那篇文章并没有产生问题中所述的预期输出!那么为什么一个没有产生预期输出的答案被标记为最佳答案并且也被投票赞成。 andlrc 的答案应该被标记为最佳答案并投票赞成,因为它毕竟会产生定义的预期输出。
  • 我已经使用了答案sed -i 's/\([[:digit:]]\)\ \([[:digit:]]\)/\1|\2/g' file.txt 加上sed -i 's/\([[:upper:]]\)\ \([[:digit:]]\)/\1|\2/g',它适用于我的文件。也许是我缺少的东西,因为我对 shell 了解不多,但它可以工作
  • 在编辑原始问题之前,Chris Maes 的回答在 15 之间留了一个空格,例如NAME4|1 5|8 因此他的回答是错误的。通过您的编辑,它会在 58 之间留下一个空格,例如NNAAME|1|5 8 并添加您的 sed 命令不会改变任何事情!他以及您添加的内容仍然没有产生您问题中所述的预期结果,因此它仍然是错误的!只有andlrc的回答是按要求做的,在名称后用管道|替换所有空格。你现在明白了吗!?
  • 好的,是的!打扰一下。我忘记了 1 和 5 之间有一个空格。

标签: bash shell spaces


【解决方案1】:

你可以用数字替换所有空格:

$ sed 's/[[:space:]]\([[:digit:]]\)/|\1/g' file
NAME1|111|2222|333
NAME2|111|22|333 
NA ME3|444|555|2
NAME4|1|5|8
N ME5|44|66|111

细分:

s/                          /   /g # Global substitute command
  [[:space:]]                      # Match a space
               [[:digit:]]         # Match a digit
             \(           \)       # Capture in \1
                              |\1  # Replace with | and captured digit

【讨论】:

  • 但是如果 NAME1 的数字只是 NAME,我应该写什么来代替“数字”?
  • 我已经更改了问题,因为问题末尾不需要数字
【解决方案2】:

您可以使用sed 表达式来做到这一点:

sed -i 's/\([[:digit:]]\)\ \([[:digit:]]\)/\1|\2/g' file.txt

输出:

NAME1|111|2222|333
NAME2|111|22|333
NA ME3|444|555|2
NAME4|1 5|8
N ME5|44|66|111

sed 命令解释:

  • -i:就地:修改file.txt
  • [[:digit:]] : 如你所想:匹配一个数字
  • \(<patter>\) :在转义括号 \(\) 之间包含一些内容,使它们成为可以引用的 pattern。因为我用了两次;在 sed 命令的第二部分;我可以使用\1\2 来指代这两种模式。

【讨论】:

  • NAME4|1 5|8 不应该在15 之间有一个|,而不是一个space
  • 是的,应该。无论如何,非常感谢,我有这个想法。我现在就试试
  • 我已经更改了问题,因为问题末尾不需要数字
  • 我在其他情况下也这样做了,它有效:sed -i 's/\([[:upper:]]\)\ \([[:digit:]]\)/\1|\2/g'
猜你喜欢
  • 2014-09-26
  • 2019-06-28
  • 2018-05-24
  • 2011-02-12
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多