Unix/命令/文本处理指南
Unix 支持多种文本处理命令。
awk 是一个强大的文本处理工具,使用正则表达式,提供了超出 #cut 和 #sed 的扩展功能。您可以在 AWK 和 AWK 入门 维基教科书中了解更多信息。
单行示例
- echo abcd |awk '/b.*d/'
- 输出与正则表达式匹配的行,类似于 grep 命令。
- echo abcd |awk '/b.*d/ {print $0}'
- 与上面相同,使用显式 print 语句。$0 代表整行。
- echo ab cd |awk '/b.*d/ {print $2}'
- 对于与正则表达式匹配的行,输出第二个字段。默认情况下,使用空格序列作为字段分隔符。因此,输出“cd”。
- echo abcd,e |awk -F, '/b.*d/ {print $2}'
- 对于与正则表达式匹配的行,输出第二个字段,由于 -F 选项,使用逗号作为字段分隔符。因此,输出“e”。
- echo abcd,e |awk '{print toupper($0)}'
- 输出所有行的大写字母。对于小写字母,使用“tolower”。
- echo a b c d | awk '{print $NF, $(NF-1)}'
- 输出最后一个字段和倒数第二个字段;NF 是字段数。
- echo ab cd | awk 'NF>=2'
- 输出字段数为 2 或更多的行。
- echo ab cd | awk '{print NF}'
- 对于每一行,输出其中的字段数。
- echo ab cd | awk 'length($2) > 1'
- 输出所有第二字段长度大于 1 的行。
- echo ab cd | awk '$2 ~ /cd/'
- 输出第二字段与正则表达式匹配的所有行。
- echo ab cd | awk '$1 ~ /ab/ && $2 ~ /cd/'
- 与上面类似,但使用由“&&”连接的两个子条件。支持 C 编程语言中已知的其他逻辑运算符。
- cat file.txt | awk 'NR >= 100 && NR <= 500'
- 输出行号在指定范围内的行(记录)。因此,充当行号过滤器。
- cat file.txt | awk 'NR == 1 || /reg.*pattern/'
- 输出第一行和与正则表达式匹配的行。
- echo abcd | awk '{gsub(/ab/,"ef");print}'
- 替换也称为替换,类似于 sed 命令;gsub 中的“g”代表全局。
- awk 'BEGIN{for(i=1;i<6;i++) print sqrt(i)}'
- 输出 1、...、5 中整数的平方根。BEGIN{} 的使用确保即使没有输入行馈送到 awk,代码也会执行。for 循环使用熟悉的 C 语言语法,sqrt 是可用的多个数学函数之一。
- awk 'BEGIN{printf "%i %.2f\n", 1, (2+3)/7}'
- 支持来自 C 语言的熟悉函数 printf,作为不需要围绕参数的括号的语句。
- awk 'BEGIN{for(i=1;i<9;i++) a[i]=i^2; for(i in a) print i, a[i]}'
- 在 awk 关联数组也称为映射或字典的帮助下,输出一对整数及其平方。输出的顺序是不确定的,这在关联数组中是常见的。awk 没有其他编程语言中已知的数组和列表的直接模拟。
- cat file.txt | awk '{sum+=$1} END{print sum}'
- 使用 END 关键字输出第一个字段(列)中值的总和。
- awk 'BEGIN{system("dir")}'
- 运行外部命令 dir;在沙箱模式下禁用。
- awk 'function abs(x) {return x < 0 ? -x : x} BEGIN{print abs(-4)}'
- 定义和使用绝对值函数。显示了 C 语言中已知的三元运算符的使用。
链接
- awk, opengroup.org
- awk 手册页, man.cat-v.org
- GNU Awk 用户指南, gnu.org
输出两个文件中共同的或独有的行,前提是文件已排序。如果文件未排序,则输出是不确定的。选项控制识别方式,例如仅输出共同的行。
示例
- seq 1 5 > file1; seq 3 7 > file2
- 将整数序列 1...5 和 3...7 输出到文件以支持以下 comm 使用示例。
- comm file1 file2
- 如果文件已排序,则输出三列,第一列是 file1 中独有的行,第二列是 file2 中独有的行,第三列是两个文件中共同的行。列默认以制表符分隔,但制表符仅用于前导缩进,并且输出的每一行都只有一列填充。
- comm -23 file1 file2
- 如果文件已排序,则输出 file1 中不在 file2 中的行。因此,对行执行集合差运算。开关表示要从输出中省略的列。
- comm -12 file1 file2
- 如果文件已排序,则输出两个文件中都存在的行。因此,对行执行集合交运算。
- printf "1\n1\n" > file1; printf "1\n" > file2; comm file1 file2
- 第一行被评为两个文件中都存在的,而 file1 的第二行被评为 file1 中独有的。因此,不仅考虑行内容,而且将重复行视为要匹配的独立项来处理。
- seq 1 5 > file1; seq 3 7 | comm file1 -
- 使用连字符 (-) 表示标准输入。
链接
将输入拆分为输出文件。拆分可以由行数和正则表达式匹配驱动。
链接
- csplit, opengroup.org
- 5.4 csplit 在 GNU Coreutils 手册中,gnu.org
输出文本文件中各行中的选定列(“字段”),并指定列分隔符。另请参见 Cut 维基教科书。
示例
- cut -f1 file.txt
- 输出每一行的第一个字段,使用制表符作为字段分隔符。
- echo a:b | cut -d: -f2
- 输出每一行的第二个字段,使用冒号作为字段分隔符。
- echo a b c | cut -d" " -f1,3
- echo a b c d e | cut -d" " -f1-3,5
- echo a b c | cut -d" " -f3,2,1
- 输出“a b c”,忽略 -f 之后的反转顺序。
- echo a b c d | cut -d" " -f2-
- 输出第二个和所有后续字段,因此为“b c d”。
- echo abcd | cut -c3,4
- 不处理字段,而是处理字符。因此,输出“cd”。
- echo abcdefgh | cut -c1-3,6-8
- 输出 abcfgh
链接
将制表符转换为空格,默认情况下每个制表符为 8 个空格。另请参见 #unexpand.
链接
- expand, opengroup.org
- 9.2 expand 在 GNU Coreutils 手册中,gnu.org
格式化文本,包括将段落重新排列为每行特定最大字符数。似乎没有被 POSIX 覆盖
链接
以不同于 #fmt 的方式限制每行最大长度。
链接
在字符编码之间转换。
示例
- iconv -f ISO-8859-2 -t UTF-8 < in.txt > out.txt
- 从 (-f) ISO-8859-2 转换为 (-t) UTF-8。
链接
- iconv, opengroup.org
- iconv 在 libiconv 文档中,gnu.org
- software/libiconv, gnu.org - 列出了支持的编码
- iconv, man7.org
- iconv, freebsd.org
- iconv, wikipedia.org
根据字段将来自多个文件的行合并在一起,假设这些文件是根据用于合并的字段排序的。
链接
添加行号。
链接
对于多个文件,将对应于行号的行连接起来,就好像每个文件是表格的一列,每个文件行是表格的一行一样。
链接
格式化输入以供打印,包括带有页眉和页脚的分页。
链接
sed,一个流编辑器,以其文本替换功能而闻名,支持正则表达式,但可以做更多。您可以在 Sed Wikibook 中了解更多信息。
替换的单行示例
- sed "s/concieve/conceive/" myfile.txt
- 替换每行中 "concieve" 的第一次出现。
- sed "s/concieve/conceive/g" myfile.txt
- 替换所有出现,因为末尾有 "g"。
- sed "s/concieve/conceive/g;s/recieve/receive/g" myfile.txt
- 执行两次替换。
- echo "abccbd" | sed "s/a\([bc]*\)d/\1/g"
- 输出 "bccb"。使用 \( 和 \) 来标记一个组,并使用 \1 来引用替换部分中的组。
- 可能只适用于 GNU sed;待验证。
- echo "abccbd" | sed -r "s/a([bc]*)d/\1/g"
- 在 GNU sed 中,它与前面的示例做同样的事情,只是使用 -r 来启用扩展正则表达式,从而避免了在 "(" 前面放置反斜杠来表示分组的必要性。
- -r 开关在 GNU sed 中可用,而在原始的 Unix sed 中不可用。
- echo "a b" | sed -r "s/a\s*b/ab/g"
- 在 GNU sed 中,输出 "ab"。使用 "\s" 来表示空格,并使用 "*" 来使前面的字符组迭代任意次数。需要 -r 来在 GNU sed 中启用扩展正则表达式。
- sed "s/\x22/'/g" myfile.txt
- 在 GNU sed 中,将每个引号替换为一个单引号。\x22 指的是十六进制 ASCII 值为 22 的字符,即引号。
- echo Hallo | sed "s/hallo/hello/gi"
- 忽略字符大小写,因为末尾有 "i"。不保留大小写,输出 "hello" 而不是 "Hello"。
- echo a2 | sed "s/[[:alpha:]]/z/g"
- 输出 z2,使用 "[[:alpha:]]",它代表任何字母。注意,字符类在手册中列为 "[:alpha:]",带有单个 "["。
链接
- sed, opengroup.org
- sed 手册页, man.cat-v.org
- sed,一个流编辑器 - GNU 手册,gnu.org
对文件中的行进行排序,输出排序后的行,并将输入保持不变。
示例
- sort file.txt
- 按字母顺序对文件进行排序。
- sort file.txt file2.txt
- 按字母顺序对两个文件的行进行排序,输出来自两个文件的一个排序后的行流。
- cat file.txt | sort
- 对 cat 创建的输入流进行排序。因此,等效于 sort file.txt。
- sort -n file.txt
- 对文件进行数字排序。因此,12 放在 2 之后,而字母顺序则不是这样。
- sort -r file.txt
- 按相反顺序对文件进行排序。因此,b 放在 a 之前。
- sort -k5,5 file.txt
- 通过 -k 对文件按第 5 个字段(列)进行排序。
- sort -t, -k5,5 file.txt
- 如上所述,通过 -t 使用逗号 (,) 作为字段分隔符。
- sort -k5,5 -k3,3 file.txt
- 首先按第 5 个字段对文件进行排序,然后按第 3 个字段进行排序。
- sort -k5,5 -k3,3n file.txt
- 如上所述,但当按第 3 个字段排序时,通过附加的 "n" 按数字顺序进行排序。
- sort -k5 file.txt
- 首先按第 5 个字段对文件进行排序,然后对所有剩余字段进行排序,忽略排序目的的第 1-4 个字段。
- sort -u file.txt
- 对文件进行排序,删除重复的行,从而确保每行输出都是唯一的。
- sort -u -k5,5 file.txt
- 按第 5 个字段对文件进行排序,仅保留具有相同键的每组行中的一个行,其中键是第 5 个字段。
链接
执行拼写检查。似乎在 POSIX 中不存在。
链接
- spell 手册页, man.cat-v.org
- GNU spell 项目, savannah.gnu.org
执行字符映射或“转换”,以及更多操作。对于某些任务,它比 sed 更简洁。
示例
- echo "a:b:c:d" | tr : \\n
- 通过冒号 (:) 分割成多行。冒号不会出现在输出中。
- echo "a b c d" | tr " " \\n
- 通过空格分割成多行。
- echo "abba" | tr ab cd
- 将 a 替换为 c,将 b 替换为 d。因此,产生 cddc。
- echo "a,b:c,d:e" | tr ,: :,
- 交换逗号和冒号。因此,产生 a:b,c:d,e。
- echo "a b c d" | tr -d " "
- 从输入中删除空格,输出 abcd。-d 代表删除。
- echo "a,b,c:d:e" | tr -dc ,
- 仅保留逗号和冒号。-c 代表补集。因此,产生 ,,::.
- echo "a,,,b,c::d" | tr -s ,
- 将逗号序列替换为一个逗号,将冒号序列替换为一个冒号。-s 代表压缩。因此,产生 a,b,c:d。
链接
将空格转换为制表符,默认情况下每个制表符占 8 个空格。
链接
- unexpand,opengroup.org
- 9.3 unexpand 在 GNU Coreutils 手册中,gnu.org
从每个相同行块中输出单行,等等。理想情况下与排序后的输入一起使用。您可以在 Uniq 维基教科书中了解更多信息。
示例
- uniq file.txt
- 对于相邻的一个或多个相同的行,只输出其中一行。
- sort file.txt | uniq
- 对相同行进行排序,然后只输出其中一行。排序确保最初不相邻但相同的行变得相邻。
- sort file.txt | uniq -u
- 只输出单行块。
- sort file.txt | uniq -d
- 输出每块的多行块中的单行,过滤掉单行。
- sort file.txt | uniq -c
- 在每行之前加上块大小。
- sort file.txt | uniq -c | sort
- 在每行之前加上块大小,并按块大小对结果进行排序。由于 uniq 输出的大小通过空格缩进,因此排序效果很好,即使是按字母顺序排列。
- sort file.txt | uniq -u -d
- 在 GNU uniq 中,不输出任何内容,因为每个选项都充当过滤器,组合在一起后它们会过滤掉所有内容。
链接