如果行只包含一次字符,如何删除该行

如果行只包含一次字符,如何删除该行

我想从仅包含一次特定字符的文件中删除一行,如果它出现多次或不存在,则将该行保留在文件中。

例如:

DTHGTY
FGTHDC
HYTRHD
HTCCYD
JUTDYC

在这里,我要删除的字符是C这样,命令应该删除行FGTHDCJUTDYC因为它们只有C一次。

我怎样才能使用sedor来做到这一点awk

答案1

awk可以将字段分隔符设置为任何内容。如果将其设置为C,那么您将拥有与 的出现次数一样多的字段 +1 C

所以如果你说awk -F'C' '{print NF}' <<< "C1C2C3"你得到4:CCC包含 3C秒,因此有 4 个字段。

您想要删除C只出现一次的行。考虑到这一点,在您的情况下,您将需要删除那些恰好有两个C- 字段的行。所以跳过它们:

$ awk -F'C' 'NF!=2' file
DTHGTY
HYTRHD
HTCCYD

答案2

sed方法:

sed -i '/^[^C]*C[^C]*$/d' input

-i选项允许就地文件修改

/^[^C]*C[^C]*$/C- 匹配只包含一次的行

d- 删除匹配的行

答案3

这可以通过以下方式完成sed

代码:

sed '/C.*C/p;/C/d' file1

结果:

DTHGTY
HYTRHD
HTCCYD

如何?

  1. 匹配并打印至少有两份Cvia的任意行/C.*C/p
  2. 删除带有Cvia的任何行/C/d,这包括步骤 1 中已打印的行
  3. 默认打印其余行

答案4

用于对文件进行脚本编辑(而不是将修改的内容打印到标准输出)的 POSIX 工具是ex.

printf '%s\n' 'g/^[^C]*C[^C]*$/d' x | ex file.txt

当然可以使用sed -i如果您的 Sed 版本支持它,请注意,如果您正在编写旨在在不同类型的系统上运行的脚本,那么它是不可移植的。


大卫·福斯特在评论中问道:

printf您使用and 不使用echo或类似的原因有吗ex -c COMMAND

答:是的。

对于printfvs.,echo这是一个可移植性的问题;参见为什么 printf 比 echo 更好? 而且使用 . 在命令之间散布换行符也更容易printf

对于printf ... | exvs.来说ex -c ...,这是一个错误处理的问题。对于这个特定的命令来说,这无关紧要,但一般来说,这很重要;例如,尝试输入

ex -c '%s/this pattern is not in the file/replacement text/g | x' filename

在脚本中。与以下内容对比:

printf '%s\n' '%s/no matching lines/replacement/g' x | ex file

第一个将挂起并等待输入;当命令收到 EOF 时,第二个将退出ex,因此脚本将继续。还有其他替代解决方法,例如s///e,但 POSIX 未指定它们。我更喜欢使用便携式形式,如上所示。

对于g命令来说,有必须最后是换行符,我更喜欢用它printf来包装命令而不是在单引号中嵌入换行符。

相关内容