删除一行的第一个字符
1. 概述
在本教程中,我们将学习如何使用 GNU/Linux 提供的工具删除一行的前n 个字符。
2. 使用cut
cut 允许我们通过长度或分隔符选择行的某些部分。
让我们使用其中的第一个来删除字符串的前三个字母。我们将告诉它删除最多第 4 个字符:
$ echo '123456789' | cut -c 4-
456789
3.使用 sed
既然我们知道要删除的字母数量是有限的,那么我们就有了一个模式。在许多情况下, sed 允许我们在模式的帮助下过滤和转换文本。
使用正则表达式,我们可以搜索前三个字符并将它们从行中删除:
$ echo '123456789' | sed -r 's/^.{3}//'
# |____||____ sed removes them
# |
# |__ search for the first three characters
使用参数 -r,我们将能够使用扩展的正则表达式。
4. 使用 grep
就像sed 一样,grep也使用文本模式进行操作。使用相同的正则表达式,我们将查找前三个字符:
$ echo '123456789' | grep -Po '^.{3}\K.*'
-Po标志指示grep将模式解释为与 Perl 兼容的正则表达式。
\K转义序列导致之前匹配的 内容(前三个字符)不包含在末尾,然后.* 匹配后面的所有内容。
更多grep用例和示例可以在 常用Linux文本查询 上找到。
5. 使用 awk
awk 使我们能够将操作应用于某些模式。
回顾我们的正则表达式,我们可以在awk脚本中使用它作为 sub的参数 来删除所需的字符:
$ echo '123456789' | awk 'sub(/^.{3}/,"")'
而且,awk还可以通过其他几种方式为我们实现这一目标。
在其余示例中,我们将使用一个我们将定义为范围的变量。虽然我们可以在没有变量的情况下做到这一点——在表达式中内联值——但是变量可以使我们的命令更具可读性,就像在编码中一样。
此外,通过引入变量,我们可以通过参数发送范围来控制范围的大小,从而保持awk脚本的完整性。因此,通过参数化,我们不会失去脚本的一般性。
回到我们的第一个近似值,让我们使用变量:
$ echo '123456789' | awk -v range="3" 'sub(sprintf("^.{%s}",range),"")'
# |____________|
# |
# Here we compose our regular expression _______|
此外,我们可以指示awk将空字符视为字段分隔符。然后,我们可以迭代每个字符打印仅从所需位置到行尾:
$ echo '123456789' | awk -F '' -v range=3 '{for (i=1; i<=NF; i++) if (i > range) printf $i; print ""}'
# |___| |________|
# | |_____ We assign the value "3" to the variable "range"
# |
# |_________ We set the input field separator as the null string and
# we let a space between the null character and the -F parameter.
更方便的方法是使用substr 函数:
$ echo '123456789' | awk -v range=3 '{print substr($0,range+1)}'
在后一种情况下,我们可以利用awk的默认行为是打印整个记录(存储在变量*$0*中),所以我们只能修改它:
echo '123456789' | awk -v range=3 '$0 = substr($0,range+1)'
6. 使用 perl
perl是 Perl 语言的解释器,它为文本处理带来了一系列强大的功能。 正如我们对sed、grep和awk的substr所做 的那样,我们可以在perl调用中应用正则表达式:
$ echo '123456789' | perl -pe 's/^.{3}//'
7. 使用参数扩展
在Bash和Zsh中可用,参数扩展对于操作字符范围很有用:
$ var="123456789"
$ echo ${var:3}
或者,仅使用Zsh:
$ var="123456789"
$ echo $var[4,-1]
这种方法的一个缺点是来自字符流的行在被剪切之前必须分配给一个变量。如果我们想做这样的事情,我们将不得不使用:
$ while read var || [[ -n $var ]]; do echo ${var:3}; done < example_file.txt
或者:
$ <command> | while read var || [[ -n $var ]]; do echo ${var:3}; done