文本操作


文档摘要

文本操作 [sort]() [uniq]() [comm]() [cmp]() [diff]() [tr]() [sed]() [awk]() [perl]() [cut]() [paste]() [column]() [pr]() 排序 对文本文件的行进行排序 如其名称所示,这个命令用于对文件进行排序。字母排序和数字排序?可以做到。对特定列进行排序?也可以。优先级多排序顺序?可以。随机排序?唯一性?几乎所有排序需求都能通过这个强大的命令满足。

文本操作

排序

对文本文件的行进行排序

如其名称所示,这个命令用于对文件进行排序。字母排序和数字排序?可以做到。对特定列进行排序?也可以。优先级多排序顺序?可以。随机排序?唯一性?几乎所有排序需求都能通过这个强大的命令满足。

选项

-R 随机排序 -r 反转排序顺序 -o 将排序结果重定向到指定的文件名,非常有用,可以原地排序文件 -n 数值排序 -V 版本排序,识别文本中的数字 -h 人类可读的数字排序,如 4K、3M 等 -k 通过键排序 -u 唯一排序 -b 在排序时忽略行首的空白字符 -t 使用 SEP 替换非空白到空白的转换

示例

sort dir_list.txt 显示标准输出上排序后的文件 sort -bn numbers.txt -o numbers.txt 数值排序 numbers.txt(忽略行首空白字符)并用排序后的输出覆盖文件 sort -R crypto_keys.txt -o crypto_keys_random.txt 随机排序并写入新文件 shuf crypto_keys.txt -o crypto_keys_random.txt 也可以使用 du -sh * | sort -h 按人类可读格式对当前目录中的文件/目录大小进行排序
$ cat ip.txt 6.2 : 897 : bar 3.1 : 32 : foo 2.3 : 012 : bar 1.2 : 123 : xyz
$ # -k3,3 means from 3rd column onwards to 3rd column $ # for ex: to sort from 2nd column till end, use -k2 $ sort -t: -k3,3 ip.txt 2.3 : 012 : bar 6.2 : 897 : bar 3.1 : 32 : foo 1.2 : 123 : xyz
$ # -n option for numeric sort, check out what happens when -n is not used $ sort -t: -k2,2n ip.txt 2.3 : 012 : bar 3.1 : 32 : foo 1.2 : 123 : xyz 6.2 : 897 : bar
$ # more than one rule can be specified to resolve same values $ sort -t: -k3,3 -k1,1rn ip.txt 6.2 : 897 : bar 2.3 : 012 : bar 3.1 : 32 : foo 1.2 : 123 : xyz

更多资源

uniq

报告或忽略重复的行

此命令更具体于识别重复项。通常需要已排序的输入,因为比较仅针对相邻行进行

选项

  • -d 仅打印重复行
  • -c 在出现次数前添加计数
  • -u 仅打印唯一行

示例

  • sort test_list.txt | uniq 以排序顺序显示 test_list.txt 的行,并删除重复行
    • uniq <(sort test_list.txt) 使用进程替换的相同命令
    • sort -u test_list.txt 相当的命令
  • uniq -d sorted_list.txt 仅打印重复行
  • uniq -cd sorted_list.txt 仅打印重复行并在行前添加重复次数
  • uniq -u sorted_list.txt 仅打印唯一行,重复行被忽略
  • uniq 在 Unix StackExchange 上的 Q&A
$ echo -e 'Blue\nRed\nGreen\nBlue\nRed\nBlack\nRed' > colors.txt $ uniq colors.txt Blue Red Green Blue Red Black Red $ echo -e 'Blue\nRed\nGreen\nBlue\nRed\nBlack\nRed' | sort > sorted_colors.txt $ uniq sorted_colors.txt Black Blue Green Red $ uniq -d sorted_colors.txt Blue Red $ uniq -cd sorted_colors.txt 2 Blue 3 Red $ uniq -u sorted_colors.txt Black Green

comm

逐行比较两个已排序的文件

没有选项时,它会以三列的形式输出:文件1独有的行、文件2独有的行和两个文件共有的行

选项

  • -1 抑制文件1独有的行
    -2 抑制文件2独有的行
    -3 抑制两个文件共有的行

示例

  • comm -23 sorted_file1.txt sorted_file2.txt 打印文件1独有的行
    • comm -23 <(sort file1.txt) <(sort file2.txt) 使用进程替换的相同命令,如果未提供已排序的输入文件
  • comm -13 sorted_file1.txt sorted_file2.txt 打印文件2独有的行
  • comm -12 sorted_file1.txt sorted_file2.txt 打印两个文件共有的行
  • comm 在 Unix StackExchange 上的 Q&A
$ echo -e 'Brown\nRed\nPurple\nBlue\nTeal\nYellow' | sort > colors_1.txt $ echo -e 'Red\nGreen\nBlue\nBlack\nWhite' | sort > colors_2.txt $ # the input files viewed side by side $ paste colors_1.txt colors_2.txt Blue Black Brown Blue Purple Green Red Red Teal White Yellow examples $ # 3 column output - unique to file1, file2 and common $ comm colors_1.txt colors_2.txt Black Blue Brown Green Purple Red Teal White Yellow $ # suppress 1 and 2 column, gives only common lines $ comm -12 colors_1.txt colors_2.txt Blue Red $ # suppress 1 and 3 column, gives lines unique to file2 $ comm -13 colors_1.txt colors_2.txt Black Green White $ # suppress 2 and 3 column, gives lines unique to file1 $ comm -23 colors_1.txt colors_2.txt Brown Purple Teal Yellow

cmp

逐字节比较两个文件

适用于比较二进制文件。如果两个文件相同,则不显示任何输出(退出状态为0)
如果有差异,则会显示第一个差异——行号和字节位置(退出状态为1)
选项 -s 允许抑制输出,这对于脚本很有用

$ cmp /bin/grep /bin/fgrep /bin/grep /bin/fgrep differ: byte 25, line 1

diff

逐行比较文件

适用于比较文本文件的旧版本和新版本
所有差异都会打印出来,如果文件太长可能不太理想

选项

  • -s 当两个文件相同时传达消息
  • -y 两列输出
  • -i 忽略大小写比较
  • -w 忽略空格
  • -r 递归比较指定两个目录中的文件
  • -q 报告文件是否不同,而不是差异的细节

示例

  • diff -s test_list_mar2.txt test_list_mar3.txt 比较两个文件
  • diff -s report.log bkp/mar10/ 如果名称相同,则无需指定第二个文件名
  • diff -qr report/ bkp/mar10/report/ 递归比较 report 和 bkp/mar10/report 目录中的文件,不匹配的文件名也会在输出中指定
    • 有关详细分析和边缘情况,请参阅此链接
  • diff report/ bkp/mar10/report/ | grep -w '^diff' 有用的技巧,仅获取不匹配文件的名称(前提是不匹配的内容不包含以“diff”开头的整行)

进一步阅读

tr

转换或删除字符。
UNIX 中的 tr 命令是一个命令行实用程序,用于转换或删除字符。它支持包括大写转小写、压缩重复字符、删除特定字符和基本查找替换在内的多种转换。它可以与 UNIX 管道一起使用,以支持更复杂的转换。

选项

  • -d 删除指定的字符
  • -c 补充要替换的字符集

如何使用 tr 命令

tr 命令的语法如下:

tr OPTION... SET1 [SET2]

tr 接受两组字符,通常是长度相同的字符,并将第一组字符替换为第二组字符中的相应字符。

一个 SET 实际上是一串字符,包括特殊转义字符。

示例

  • tr a-z A-Z < test_list.txt 将小写字母转换为大写字母
  • tr -d ._ < test_list.txt 删除点和下划线字符
  • tr a-z n-za-m < test_list.txt > encrypted_test_list.txt 通过将每个小写字母替换为其后的第13个字母来加密
  • 如何删除特定字符
echo 'clean this up' | tr -d 'up' clean this
  • 如何压缩重复字符

要压缩指定集合中的重复字符实例,请使用 -s 选项。这会移除重复的字符实例。在以下示例中,一个带有过多空格的字符串会被压缩以去除它们。

echo 'too many spaces here' | tr -s '[:space:]' too many spaces here
  • 如何查找和替换

tr 工具适用于简单的查找和替换操作,在这种操作中,一个字符应替换为另一个字符。以下示例将下划线替换为空格。

echo "some_url_that_I_have" | tr "_" "-" some-url-that-I-have

阅读更多

sed

流编辑器,用于过滤和转换文本

选项

  • -n 抑制模式空间的自动打印
  • -i 原地编辑文件(如果提供了后缀,则创建备份)
  • -r 使用扩展的正则表达式
  • -e 向要执行的命令添加脚本
  • -f 向要执行的命令添加脚本文件的内容

命令

- d 删除模式空间 - p 打印模式空间 - s 查找和替换

范围

默认情况下,sed 对所有输入内容进行操作。可以通过行号范围、搜索模式或两者混合来细化此操作

  • n,m 第 n 行到第 m 行的范围,包括 n 和 m
  • i~j 从第 i 行开始,每隔 j 行操作一次
    • 1~2 表示第 1 行、第 3 行、第 5 行等,即奇数行
    • 5~3 表示第 5 行、第 8 行、第 11 行等
  • n 仅第 n 行
  • $ 仅最后一行
  • /pattern/ 匹配模式的行
  • n,/pattern/ 从第 n 行到匹配模式的行
  • n,+x 第 n 行及其后的 x 行
  • /pattern/,m 匹配模式的行到第 m 行
  • /pattern/,+x 匹配模式的行及其后的 x 行
  • /pattern1/,/pattern2/ 匹配模式1的行到匹配模式2的行
  • /pattern/I 匹配模式的行,模式不区分大小写

选择性删除(d)示例

  • sed '/cat/d' story.txt 删除包含 cat 的所有行
  • sed '/cat/!d' story.txt 删除不包含 cat 的所有行
  • sed '$d' story.txt 删除文件的最后一行
  • sed '2,5d' story.txt 删除文件中的第 2、3、4、5 行
  • sed '1,/test/d' dir_list.txt 从文件开头到首次出现包含 test 的行的所有行(匹配的行也被删除)
  • sed '/test/,$d' dir_list.txt 从包含 test 的行到文件末尾的所有行

选择性打印(p)示例

  • sed -n '5p' story.txt 打印第 5 行,-n 选项覆盖 sed 的默认打印行为
    • 在大文件上使用 sed '5q;d' story.txt。更多信息请参阅
  • sed -n '/cat/p' story.txt 打印包含 cat 文本的所有行
    • 等价于 sed '/cat/!d' story.txt
  • sed -n '4,8!p' story.txt 打印除了第 4 到第 8 行以外的所有行
  • man grep | sed -n '/^\s*exit status/I,/^$/p' 从手册中提取命令的退出状态信息
    • /^\s*exit status/I 以不区分大小写的方式检查以 'exit status' 开头的行,行首可能有空白字符
    • /^$/ 空行
  • man ls | sed -n '/^\s*-F/,/^$/p' 从手册中提取命令选项的信息
    • /^\s*-F/ 以选项 '-F' 开头的行,行首可能有空白字符

查找和替换(s)示例

  • sed -i 's/cat/dog/g' story.txt 在 story.txt 中将每个 cat 替换为 dog
  • sed -i.bkp 's/cat/dog/g' story.txt 除了原地文件编辑外,还会创建备份文件 story.txt.bkp,以防出错可以恢复原始文件
    • sed -i.bkp 's/cat/dog/g' *.txt 在当前目录中对所有以 .txt 结尾的文件执行操作
  • sed -i '5,10s/cat/dog/gI' story.txt 在第 5 到第 10 行中将每个 cat(由于修饰符 I 不区分大小写)替换为 dog
  • sed '/cat/ s/animal/mammal/g' story.txt 在包含 cat 的所有行中将 animal 替换为 mammal
    • 由于未使用 -i 选项,输出显示在标准输出上且 story.txt 未更改
    • 范围和命令之间的间隔是可选的,sed '/cat/s/animal/mammal/g' story.txt 也可以使用
  • sed -i -e 's/cat/dog/g' -e 's/lion/tiger/g' story.txt 将每个 cat 替换为 dog 和每个 lion 替换为 tiger
    • 可以使用任意数量的 -e 选项
    • sed -i 's/cat/dog/g ; s/lion/tiger/g' story.txt 替代语法,分号周围的间隔是可选的
  • sed -r 's/(.*)/abc: \1 :xyz/' list.txt 在 list.txt 的每行前后分别添加前缀 'abc: ' 和后缀 ' :xyz'
  • sed -i -r "s/(.*)/(basename PWD)/\1/" dir_list.txt 在每行开头添加当前目录名和斜杠字符
    • 注意双引号用于执行命令替换
  • sed -i -r "s|.*|$HOME/\0|" dir_list.txt 在每行开头添加主目录和斜杠
    • 由于 $HOME 的值本身包含斜杠字符,我们不能使用 / 作为分隔符
    • 除反斜杠或换行符外的任何字符都可以用作分隔符,例如 | # ^ 有关更多信息,请参阅此链接
    • \0 回引用包含整个匹配字符串

更多资源

awk

模式扫描和文本处理语言

awk 得名于其作者Alfred Aho、Peter Weinberger和Brian Kernighan。

语法

  • awk 'BEGIN {初始化} 条件1 {语句} 条件2 {语句}... END {结束}'
    • BEGIN {初始化} 用于初始化变量(可以是用户定义的或awk内置的变量),执行一次 - 可选块
    • 条件1 {语句} 条件2 {语句}... 对输入的每一行执行操作,条件是可选的,可以使用一个或多个带/不带条件的{}块
    • END {结束} 在程序结束时执行一次 - 可选块
  • awk ' {print $1,$3} ' > 使用标准输入仅打印第一列和第三列

cut

从每行中移除部分

对于具有明确分隔符的列操作,cut命令非常方便

示例

  • ls -l | cut -d' ' -f1 首列 ls -l
    • -d 选项指定分隔符字符,在这种情况下是单个空格字符(默认分隔符是制表符)
    • -f 选项指定要打印的字段,用逗号分隔,在这种情况下是字段1
  • cut -d':' -f1 /etc/passwd 打印 /etc/passwd 文件的第一列
  • cut -d':' -f1,7 /etc/passwd 打印 /etc/passwd 文件的第一列和第七列,用冒号字符分隔
  • cut -d':' --output-delimiter=' ' -f1,7 /etc/passwd 使用空格作为分隔符打印第一列和第七列

paste

合并文件中的行

示例

  • paste list1.txt list2.txt list3.txt > combined_list.txt 将三个文件按列合并到一个文件中,条目由制表符分隔
  • paste -d':' list1.txt list2.txt list3.txt > combined_list.txt 条目由冒号字符分隔而不是制表符
    • 查看 pr 命令以使用多字符分隔符
$ # joining multiple files $ paste -d, <(seq 5) <(seq 6 10) 1,6 2,7 3,8 4,9 5,10 $ paste -d, <(seq 3) <(seq 4 6) <(seq 7 10) 1,4,7 2,5,8 3,6,9 ,,10
  • 单列转为多列
$ seq 5 | paste - - 1 2 3 4 5 $ # specifying different output delimiter, default is tab $ seq 5 | paste -d, - - 1,2 3,4 5, $ # if number of columns to specify is large, use the printf trick $ seq 5 | paste $(printf -- "- %.s" {1..3}) 1 2 3 4 5
  • 将所有行合并为一行
$ seq 10 | paste -sd, 1,2,3,4,5,6,7,8,9,10 $ # for multiple character delimiter, perl can be used $ seq 10 | perl -pe 's/\n/ : / if(!eof)' 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10

column

列出数据

$ cat dishes.txt North alootikki baati khichdi makkiroti poha South appam bisibelebath dosa koottu sevai West dhokla khakhra modak shiro vadapav East handoguri litti momo rosgulla shondesh $ column -t dishes.txt North alootikki baati khichdi makkiroti poha South appam bisibelebath dosa koottu sevai West dhokla khakhra modak shiro vadapav East handoguri litti momo rosgulla shondesh

pr

转换文本文件以便打印

$ pr sample.txt 2016-05-29 11:00 sample.txt Page 1 This is an example of adding text to a new file using cat command. Press Ctrl+d on a newline to save and quit. Adding a line of text at end of file
  • 包括将文本文件转换为带有页眉、页脚、页码等的打印格式,双倍行距文件,按列合并多个文件等
$ # single column to multiple column, split vertically $ # for example, in command below, output of seq is split into two $ seq 5 | pr -2t 1 4 2 5 3 $ # different output delimiter can be used by passing string to -s option $ seq 5 | pr -2ts' ' 1 4 2 5 3 $ seq 15 | pr -5ts, 1,4,7,10,13 2,5,8,11,14 3,6,9,12,15
  • 使用 -a 选项拆分
$ seq 5 | pr -2ats' : ' 1 : 2 3 : 4 5
$ seq 15 | pr -5ats, 1,2,3,4,5 6,7,8,9,10 11,12,13,14,15
```bash $ # 使用 $ 扩展表示由转义字符(如 \t 表示制表符)定义的字符 $ seq 5 | pr -3ts$'\t' 1 3 5 2 4 $ # 或者省略 -s 的参数,因为制表符是默认值 $ seq 5 | pr -3ts 1 3 5 2 4
  • The default PAGE_WIDTH is 72
  • The formula (col-1)*len(delimiter) + col seems to work in determining minimum PAGE_WIDTH required for multiple column output
  • The -J option will help in turning off line truncation
$ seq 74 | pr -36ats, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36 37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72 73,74 $ seq 74 | pr -37ats, pr: 页面宽度太窄 $ # (37-1)*1 + 37 = 73 $ seq 74 | pr -Jw 73 -37ats, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74 $ # (3-1)*4 + 3 = 11 $ seq 6 | pr -Jw 10 -3ats'::::' pr: 页面宽度太窄 $ seq 6 | pr -Jw 11 -3ats'::::' 1::::2::::3 4::::5::::6
  • Use -m option to combine multiple files in parallel
$ pr -mts', ' <(seq 3) <(seq 4 6) <(seq 7 9) 1, 4, 7 2, 5, 8 3, 6, 9

进一步阅读

原始内容、致谢和参考文献

声明:
本文件灏天文库团队进行了翻译。尽管我们力求准确,但请注意,翻译可能包含错误或不准确之处。原文档以其原始语言为准。我们不对因使用此翻译而产生的任何误解或误译负责。


作者与出处
原作者: Tikam02
来源:Tikam02
许可证:MIT
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: Tikam02 转发
评论区 (0)
U