awk 不同的分隔符 - 空格分隔符

今天用 awk 格式化字符串的时候,发现了一个奇怪现象,查看了 awk 手册后,特以此文记录。html

示例文本内容

后文全部 awk 语名中出现的 file.txt 内容均以下:express

# cat -A file.txt
     1^Iroot:x:0:0:root:/root:/bin/bash$
     2^Ibin:x:1:1:bin:/bin:/sbin/nologin$
     3^Idaemon:x:2:2:daemon:/sbin:/sbin/nologin$

现象描述

经过 awk -F 的 "[]" 指定多个分隔符(包含空格)的时候,连续的空格被分隔成了多个字段。bash

awk 默认以空白字符(包含空格、TAB 字符、换行符)作为分隔符,为了更直观对比,此处示例直接经过 -F 参数指定。简单示例对比下:app

咱们先指定空格作为分隔符来获取第二个字段ide

# awk -F " " '{print NF, $2}' file.txt
2 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
2 daemon:x:2:2:daemon:/sbin:/sbin/nologin

再经过 [] 指定空格分隔符来获取this

# awk -F "[ ]" '{print NF, $6}' file.txt
6 1 root:x:0:0:root:/root:/bin/bash
6 2 bin:x:1:1:bin:/bin:/sbin/nologin
6 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

是否是好奇怪,咱们经过 -F " " 作为分隔符的时候,每行只有 2 个字段,而经过 -F "[ ]" 作分隔符的时候,每行共有 6 个字段。$1-$5 获取的值为空,而 $6 确打印了所有内容。spa

查看 awk 手册:
4.5.1 Whitespace Normally Separates Fieldscode

awk interpreted this value in the usual way, each space character would separate fields, so two spaces in a row would make an empty field between them. The reason this does not happen is that a single space as the value of FS is a special case—it is taken to specify the default manner of delimiting fields.

If FS is any other single character, such as ",", then each occurrence of that character separates two fields. Two consecutive occurrences delimit an empty field. If the character occurs at the beginning or the end of the line, that too delimits an empty field. The space character is the only single character that does not follow these rules.

4.5.2 Using Regular Expressions to Separate Fields orm

There is an important difference between the two cases of ‘FS = " "’ (a single space) and ‘FS = "[ \t\n]+"’ (a regular expression matching one or more spaces, TABs, or newlines). For both values of FS, fields are separated by runs (multiple adjacent occurrences) of spaces, TABs, and/or newlines. However, when the value of FS is " ", awk first strips leading and trailing whitespace from the record and then decides where the fields are.

awk 手册htm

这两段内容恰好解释了这个奇怪的现象。大概意思就是:

  • 行中的连续空格不会分隔空字段。当 FS 的值为 " " 时,awk 首先从记录中去除行首和行尾的空白,而后再分割字段。
  • 若是 FS 是其余字符,好比”,“,连续两次出现将分隔一个空字段。若是字符出如今行首或行尾,也会分隔空字段。空格字符作为默认分隔符,是惟一不遵照这些规则的字符。
  • 若是经过 -F "[ ]" 指定,执表示经过单个空格分隔,此时,将失去其作为默认分隔符的特性,与其它字符同样,遵照一样的分隔规则。

总结

结合上面内容,咱们再来看几个示例,对今天的内容作个总结。

示例:
awk 不同的分隔符 - 空格分隔符

总结:

  • 示例一,没有指定分隔符,用的默认分隔符,此时行首的连续空白字符被自动去除。
  • 示例二,指定分隔符为空格,等价于默认分隔符。
  • 示例三,指定分隔符为一个或多个连续的“冒号或 tab 键“,此时行首多个连续空白字符被一块儿计入第一个字段。
  • 示例四,指定分隔符为一个或多个连续的”空白字符或冒号或 tab 键“,此时行首多个连续的空白字符被分隔为一个独立的字段。
相关文章
相关标签/搜索