前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux 命令 | 每日一学,文本处理之内容分割排序实践

Linux 命令 | 每日一学,文本处理之内容分割排序实践

作者头像
全栈工程师修炼指南
发布2024-09-24 18:34:49
870
发布2024-09-24 18:34:49
举报
文章被收录于专栏:全栈工程师修炼之路

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]

0x01 Linux 文本分割排序命令

cut 命令 - 提取部分文本内容

描述:用来显示行中的指定部分,删除文件中指定字段,在文件的每一行中提取片断, 在每个文件 FILE 的各行中, 把提取的片断显示在标准输出。

参数语法:

代码语言:javascript
复制
-b, --bytes=LIST       # 仅显示行中指定直接范围的内容;
-c, --characters=LIST  # 仅显示行中指定范围的字符;
-d, --delimiter=DELIM  # 指定字段的分隔符,默认的字段分隔符为“TAB”;
-f, --fields=LIST      # 显示指定字段的内容;
-n  # 与“-b”选项连用,不分割多字节字符;
-s, --only-delimited    # 不打印不包含分隔符的行
    --output-delimiter=<字段分隔符> # 指定输出内容是的字段分割符;
-z, --zero-terminated   # 当行分隔符是NUL,不是换行符
--complement  # 补足被选择的字节、字符或字段;(取反显示)

# 使用且只使用 -b, -c 或 -f 中的一个选项. LIST 由 一个 范围 (range) 或 逗号 隔开的多个范围组成. 范围是下列形式 之一:
N  : 第 N 个 字节, 字符 或 字段, 从 1 计数 起
N- : 从 第 N 个 字节, 字符 或 字段 直至 行尾
N-M:从 第 N 到 第 M (并包括 第M) 个 字节, 字符 或 字段
-M : 从 第 1 到 第 M (并包括 第M) 个 字节, 字符 或 字段

温馨提示:若如果没有指定文件FILE, 或FILE是 -, 就从标准输入读取数据.

使用示例:

代码语言:javascript
复制
# 范例:
$ cat test.txt 
No Name Mark Percent
01 tom 69 91
02 jack 71 87
03 alex 68 98

# 示例1:采用默认的<tab>分割然后使用-f来提取指定字段
cut -f 1 test.txt
# No
# 01
# 02
# 以:分割文件,输出第一,二,三个字段(指定分隔符)
cat /etc/passwd | cut -f 1,2,3 -d ":" | head -5

# 示例2.输出passwd中得第一个字符
cat /etc/passwd | cut -b 1
cat /etc/passwd | cut -b 1-4 | head -5    #输出文件的前四个字符

weiyigeek.top-cut示例1融合

代码语言:javascript
复制
# 示例3.以特殊符号进行分割时 $'\n' (换行), $'\t'(Tab建),按照反斜杠控制的字符转换进行转换(printf 输出格式):
cat test | cut -F1,3 -D $'\T'   # 以TAB作为分割符号
cat test | cut -f1,3 -d $'\n'   # 以换行符作为分割符号

# 示例4.打印0字段到3字段得数据和排除
cut -d $'\t' -f -3 test.txt 
#--complement 选项提取指定字段之外的列(打印除了第二列之外的列):
cut -f2 --complement test.txt 
# No Mark Percent
# 01 69 91
# 02 71 87
# 03 68 98

# 示例5.将所有行的2-3字符打印出来
cut -c 2,3 test.txt 
cut -c 1-4 test.txt  #两种形式都可以
echo $RANDOM | md5sum | cut -c 1-8  #值得学习 
60354ab3

# 示例6.采用制定输出符输出分割的字符
$ cut -d " " -f 1,3 --output-delimiter='-' init.sh
#!/bin/sh
npm-set
npm-set
npm--g
npm---save
hexo

# 示例7.采用切割排序去重进行图片目录创建
for dir in $(cut -d " " -f 3 gzkz.sh  | cut -d "/" -f 4 | sort | uniq );do  mkdir -vp ${dir}; done 
mkdir: 已创建目录 "0101"
....
mkdir: 已创建目录 "0140"

weiyigeek.top-cut示例

示例8.多种方法截取计算机分区使用率,条条大路通罗马。

代码语言:javascript
复制
# 方式1.通用方式
$ df -Th | tr -s ' ' | cut -d " " -f 6,7 | tail -n +2

# 方式2.不同磁盘空间大小可能不通用,此处是截取43~到末尾位置的字符
df -Th | cut -c 43- | tail -n +2
  0% /dev
  1% /run
 37% /
  1% /dev/shm
  0% /run/lock
  0% /sys/fs/cgroup

温馨提示:在使用-d参数指定特殊分割字符的时候需要采用''单引号否则会报错;

示例9.获取当前主机系统网卡名称,及其 ipv4、6地址。

代码语言:javascript
复制
$ ifconfig | egrep "inet|UP" | tr -s " " | sed -e "s# inet ##g"  -e "s# inet6 ##g" | cut -d " " -f 1
br-30ecd6f3415e:
172.25.0.1
fe80::42:30ff:fea2:a871
br-460aa491632b:
172.21.0.1
fe80::42:f0ff:feb2:a1f4
br-5baaf052dfdc:

示例10.使用tr生成计算的字符串。

代码语言:javascript
复制
echo {1..10} | cut -d ' ' -f 1-10 --output-delimiter='+' | bc
55

tr 命令 - 转换或删除文件中的字符

描述:这个命令是及其重要的可以和三剑客联合使用达到非一般的效果,可以对来自标准(stdin)输入的字符进行替换、压缩和删除。它可以将一组字符变成另一组字符,经常用来编写优美的单行命令,作用很强大。

语法参数

代码语言:javascript
复制
tr [选项]... SET1 [SET2]

# 选项
-c或--complerment:取代所有不属于第一字符集的字符;
-d或--delete:删除所有属于第一字符集的字符;
-s或--squeeze-repeats:把连续重复的字符以单独一个字符表示;
-t或--truncate-set1:先删除第一字符集较第二字符集多出的字符。

#SET 是一组字符串,一般都可按照字面含义理解。解析序列如下:
  \NNN 八进制值为NNN 的字符(1 至3 个数位)
  \\  反斜杠
  \a  终端鸣响
  \b  退格
  \f  换页
  \n  换行
  \r  回车
  \t  水平制表符
  \v  垂直制表符
  字符1-字符2  #从字符1 到字符2 的升序递增过程中经历的所有字符 [0-9]
  [字符*]      #在SET2 中适用,指定字符会被连续复制直到吻合设置1 的长度
  [字符*次数]  #对字符执行指定次数的复制,若次数以 0 开头则被视为八进制数
  [:alnum:] 所有的字母和数字
  [:alpha:] 所有的字母
  [:cntrl:] 所有的控制字符
  [:digit:] 所有的数字
  [:graph:] 所有的可打印字符,不包括空格
  [:lower:] 所有的小写字母
  [:upper:] 所有的大写字母
  [:print:] 所有的可打印字符,包括空格
  [:punct:] 所有的标点字符
  [:space:] 所有呈水平或垂直排列的空白字符
  [:blank:] 所有呈水平排列的空白字符
  [:xdigit:] #所有的十六进制数
  [=字符=]  #所有和指定字符相等的字符

# 字符集1:指定要转换或删除的原字符集。
# 字符集2:指定要转换成的目标字符集。

Tips: 当执行转换操作时,必须使用参数"字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数"字符集2”;

实际案例

代码语言:javascript
复制
# 1.字符替换'A-Z' 和 'a-z'都是集合,集合是可以自己制定的,例如:'ABD-}'、'bB.,'、'a-de-h'、'a-c0-9'都属于集合,集合里可以使用'\n'、'\t',可以可以使用其他ASCII字符。
echo "HELLO WORLD" | tr 'A-Z' 'a-z'    # 将输入字符由大写转换为小写:
# hello world
echo "HELLO WORLD" | tr 'HLW' 'hlw'
# hEllO wORlD

# 2.注意当字符集1集合数量大于字符集2集合数量的时候,便会用字符集2最后一个字符来替换
$echo "HELLO WORLDW" | tr 'HLW' 'hl'  
# hEllO lORlDl

# 3.删除字符串中的数字
echo "hello 123 world 456" | tr -d '0-9' 
# hello world 

# 4.将文件里面制表符(tab)转换为空格:
cat text | tr '\t' ' '
# hello-world

# 5.输入重定向的内容进行替换,以及输入重定向的字符串进行替换(注意区别)
$ tr 'a-z' 'A-Z' < /etc/issue
# \S
# KERNEL \R ON AN \M
$ tr 'a-z'  'A-Z' <<< "/etc/issue"
# /ETC/ISSUE

# 6.依次对应对应替换:
cat 1.txt | tr -t "ello" "Hell"
# HHlll Wlrld

# 7.字符集补集,从输入文本中将不在补集中的所有字符删除 -c "只留下指定的字符集":
# 此例中,补集中包含了数字0~9、空格和换行符\n,所以没有被删除,其他字符全部被删除了
echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -d -c '0-9 \n' 
# 1 2 3 4

# 8.用tr压缩字符,可以压缩输入中重复的字符(-s): 
echo "thissss is a text linnnnnnne." | tr -s 'sn' 
# this is a text line. 

# 9.取消显示多个空白行,即连续换行(常用)
grep -v -E  '^#' /etc/ssh/sshd_config | tr -s '\n'  

# 10.将连续重复的空格字符替换为一个,并使用:来替换空格
$ df -Th | tr -s ' ' : 
文件系统:类型:容量:已用:可用:已用%:挂载点
devtmpfs:devtmpfs:4.0M:0:4.0M:0%:/dev
tmpfs:tmpfs:866M:0:866M:0%:/dev/shm
tmpfs:tmpfs:347M:8.4M:338M:3%:/run
/dev/mapper/rl-root:xfs:67G:2.4G:65G:4%:/
/dev/mapper/rl-home:xfs:32G:258M:32G:1%:/home
/dev/sda2:xfs:960M:251M:710M:27%:/boot
/dev/sda1:vfat:599M:7.0M:592M:2%:/boot/efi
tmpfs:tmpfs:174M:0:174M:0%:/run/user/0

# 11.巧妙使用tr做数字相加操作(值得学习)
echo 1 2 3 4 5 6 7 8 9 | xargs -n1 | echo $[ $(tr '\n' '+') 0 ]
# 45

# 12.删除Windows文件"造成”的'^M'字符,类似dos2unix的作用 (值得学习)
cat file | tr -s "\r" "\n" > new_file 
cat file | tr -d "\r" > new_file

# 13.使用字符类来进行替换或者删除操作。
echo "qwe1234,./zxcad" | tr -d -c '[:digit:] \n'  #-c 相当于取反的效果
# 1234
echo "qwe1234,./zxcad" | tr -d '[:punct:]'        # 删除所有的标点字符
# qwe1234zxcad
echo "qwe1234,./zxcad" | tr -d -c '[:punct:]  \n' #删除所有非标点字符
# ,./

# 14.删除所有特殊符号
cat 20200524113201-index.html.log |  tr -d '[:cntrl:][:punct:]'
  # 12a13 var monitorcqzsk605c606 script script 

# 15.从文件中读取字符串进行替换(值得学习)
tr ' ' '\n' < weiyigeek.top.txt
tr '\r\n' '\n' <weiyigeek.top.txt 

# 16.分隔字符串采用空格来分隔字符串,然后以数组的形式输出;
array=($(echo "hello,shell,split,test"  | tr ',' ' ') )  
for var in ${array[@]}; do
   echo $var
done 

# 17.删除提取系统版本的多余字符串
grep -e "^VERSION=" /etc/os-release | sed "s#VERSION=##g" | tr -d '[:punct:][:space:]'
grep -e "^VERSION=" /etc/os-release | cut -f 2 -d "=" | tr -d '[:punct:][:space:]'

# 18.生成随机密码
tr -dc [:alnum:][:print:] < /dev/urandom | head -c 12
  # FKo!cnQ*!-@|

paste 命令 - 文件行合并

描述:此命令用于,将每个指定文件里的各行整合到对应一行里写到标准输出,之间用制表符分隔。如果没有指定文件,或者文件为"-",则从标准输入读取。

语法参数:

代码语言:javascript
复制
用法:paste [选项]... [文件]...

# 必选参数对长短选项同时适用。
  -d, --delimiters=列表    改用指定列表里的字符替代制表分隔符
  -s, --serial             串行方式输出,即合并为一行显示
  -z, --zero-terminated    以 NUL 字符而非换行符作为行尾分隔符

示例演示:

代码语言:javascript
复制
# 范例文件
tee alpha.log <<EOF
A
B
C
D
EOF

seq 1 6 | tee digit.log

示例1.默认情况下,paste命令会以制表符作为分隔符来合并文件行:

代码语言:javascript
复制
# 缺省情况
$ paste alpha.log digit.log
A       1
B       2
C       3
D       4
        5
        6

# 指定制表符
$ paste -d ":" alpha.log digit.log
A:1
B:2
C:3
D:4
:5
:6

示例2.使用-s选项,paste命令会以串行方式输出:

代码语言:javascript
复制
$ paste -s alpha.log
A       B       C       D

$ paste -s digit.log
1       2       3       4       5       6

$ paste -s -d ":" alpha.log digit.log
A:B:C:D
1:2:3:4:5:6

示例3.与bc联用快速计算表达式。

代码语言:javascript
复制
$ seq 1 10 | paste  -s -d "+" | bc
55

示例4.与chpasswd连用批量修改用户密码

代码语言:javascript
复制
# 用户列表
tee user.txt <<EOF
weiyigeek
user1
user2
EOF

# 随机密码
for i in $(cat user.txt); do
  tr -dc [:alnum:][:print:] < /dev/urandom | head -c 12 >> passwd.txt
  echo >> passwd.txt
done

$ paste -d ':' user.txt passwd.txt
weiyigeek:\/f/5&(x/4@?
user1:*UU~k_1;$cdM
user2:[hCoK${{Is+c

// # 修改密码
paste -d ':' user.txt passwd.txt | chpasswd

sort 命令 - 文件内容排序

描述:在Linux里非常有用,它将文件文本进行排序并将排序结果标准输出,sort命令既可以从特定的文件,也可以从stdin中获取输入。

参数语法:

代码语言:javascript
复制
用法:sort [选项]... [文件]...
 或:sort [选项]... --files0-from=F

# 参数:
  -b, --ignore-leading-blanks   忽略前导的空白区域
  -d, --dictionary-order        只考虑空白区域和字母字符
  -f, --ignore-case             忽略字母大小写
  -g, --general-numeric-sort    按照常规数值排序
  -i, --ignore-nonprinting      只排序可打印字符
  -M, --month-sort              比较 (未知) < "一月" < ... < "十二月" 在LC_ALL=C 时为(unknown) < 'JAN' < ... < '`DEC'
  -h, --human-numeric-sort      使用易读性数字(例如:2K 1G-即文件大小排序)
  -n, --numeric-sort            根据字符串数值比较(数字排序,默认是升序)
  -R, --random-sort             根据随机hash 排序
      --random-source=文件      从指定文件中获得随机字节
  -r, --reverse                 逆序输出排序结果
  --sort=WORD                   按照WORD 指定的格式排序:一般数字-g,高可读性-h,月份-M,数字-n,随机-R,版本  "general-numeric" - "human-numeric" - "month" - "numeric" - "random" - "version"
  -V, --version-sort            在文本内进行自然版本排序

# 其他选项:
--batch-size=NMERGE       一次最多合并NMERGE 个输入;如果输入更多则使用临时文件
-c, --check, --check=diagnose-first   检查输入是否已排序,若已有序则不进行操作
-C, --check=quiet, --check=silent     类似-c,但不报告第一个无序行
    --compress-program=程序   使用指定程序压缩临时文件;使用该程序的-d 参数解压缩文件
    --debug                   为用于排序的行添加注释,并将有可能有问题的用法输出到标准错误输出
    --files0-from=文件        从指定文件读取以NUL 终止的名称,如果该文件被指定为"-"则从标准输入读文件名
-k, --key=位置1[,位置2]       在位置1 开始一个key,在位置2 终止(默认为行尾)参看POS语法
# 补充-k选项的具体语法格式:
# FStart(字段).CStart(列) Modifie,FEnd.CEnd Modifier
# -------Start--------,-------End--------
# FStart.CStart 选项  ,  FEnd.CEnd 选项
# Start部分也由三部分组成于End部分以`,`分割,其中的Modifier部分就是我们之前说过的类似n和r的选项部分;,
# - 其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。
# - 如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

-u, --unique     # 配合-c,严格校验排序;不配合-c,则只输出一次排序结果(可以去重复)
-m, --merge                   合并已排序的文件,不再进行排序
-o, --output=文件             #将结果写入到文件而非标准输出
-s, --stable                  禁用last-resort 比较以稳定比较算法
-S, --buffer-size=大小        指定主内存缓存大小
-t, --field-separator=分隔符  #使用指定的分隔符代替非空格到空格的转换 类似于awk的-F,cut的-d选项;
-T, --temporary-directory=目录        使用指定目录而非$TMPDIR 或/tmp 作为临时目录,可用多个选项指定多个目录
--parallel=N                      将同时运行的排序数改变为N
-z, --zero-terminated 以0 字节而非新行作为行尾标志

# 指定的大小可以使用以下单位之一:
内存使用率% 1%,b 1、K 1024 (默认),M、G、T、P、E、Z、Y 等依此类推

实际案例:

代码语言:javascript
复制
# 示例1.会按照先字母后数字进行排序 (Default)即依次按ASCII码值进行比较,最后将他们按升序输出。
# 默认,总是以第一个数据来排序, 而且默认是以字符串形式来排序,所以由字母 a 开始升序排序 (可以不加上-k 1,1)
sort -n 1.txt
# admin
# blog
# pass
# 123

# 示例2.去重复后排序
echo -e " 10.0.0.1 \n 10.0.0.2 \n 10.0.0.2 \n 10.0.0.1 \n 10.0.0.1 \n 10.0.0.3 " | sort -u
#  10.0.0.1
#  10.0.0.2
#  10.0.0.3

# 示例3.指定分隔符与位置去掉重复值
sort -t ":" -k 1,1 /etc/passwd # 内容是以 : 来分隔的,以第一栏第一个单词排序来排序(默认按照字母排序)
cat /etc/passwd | sort -t ':' -k 7 -u
cat /etc/passwd | sort -t ':' -k 3n      #用数字排序,默认是以字符串来排序的
cat /etc/passwd | sort -t ':' -k 3nr     #倒序排列,默认是升序排序

# 以用户名字母正向排序
cut -d ":" -f1,3 /etc/passwd | sort -t ":" -n 
  # adm:3
  # apache:889
  # bin:1
  # chrony:985
  # clevis:997
  # cockpit-ws:987
  # cockpit-wsinstance:986
  # daemon:2
  # dbus:81

# 以用户名id正向排序,注意-n参数的作用。
cut -d ":" -f1,3 /etc/passwd | sort -t ":" -k 2 -n
  root:0
  bin:1
  daemon:2
  adm:3
  lp:4
  sync:5
  shutdown:6
  halt:7

weiyigeek.top-sort命令排序图

代码语言:javascript
复制
# 示例4.-k选项基础使用于进阶
# 从公司英文名称的第二个字母开始进行排序:
$ sort -t ' ' -k 1.2 facebook.txt  #-k 1.2 表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序
# baidu 100 5000 #baidu因为第二个字母是a而名列榜首。
# sohu 100 4500 #sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。
# google 110 5000 
# guge 50 3000 #guge只能屈居第四了。

# 只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:
$ sort -t ' ' -k 1.2,1.2 -nrk 3,3 facebook.txt  
# n 数字/ -r 反向  # -k 3,3 指定员工工资域
# baidu 100 5000  # 使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序
# google 110 5000
# sohu 100 4500
# guge 50 3000

# 对/etc/passwd,先以第六个域的第2个字符到第4个字符进行正向排序,再基于第一个域进行反向排序
$ cat /etc/passwd | sort -t':' -k 6.2,6.4 -k 1r

# 示例5.个人理解,对文件中内容以,号分割然后再第一个域的第二个字母开始到第五个字母机进行逆向排序(降序),然后去掉重复内容;
$ sort -t "," -rk 1.2,1.5 -u file.txt 

# 示例6.使用命令针对IP与MAC进行处理
$ sort -t '.' -k 3.1,3.1nr -k4.1,4.3nr arp.txt
172.25.27.33 16-15-16-EE-76-BD
192.168.137.26 16-15-16-EE-76-BD
192.168.137.1 16-15-16-EE-76-BD
255.255.255.240 16-15-16-EE-76-BD

weiyigeek.top-sort示例2

示例7.监控磁盘使用率情况,并从大小到大进行分区排序:

代码语言:javascript
复制
$ df | tr -s " " % | cut -d "%" -f5,6 | tr -s "%" "," | tail -n +2 | sort -t "," -k 1 -nr
  # 27,/boot
  # 6,/run
  # 4,/
  # 2,/boot/efi
  # 1,/home
  # 0,/run/user/0
  # 0,/dev/shm
  # 0,/dev/cdrom

uniq 命令 - 文件文本去重

描述:此命令用于报告或忽略文件中的重复行,常与sort命令结合使用

语法参数:

代码语言:javascript
复制
uniq [选项]... [文件]

输入文件:指定要去除的重复行文件。如果不指定此项,则从标准读取数据;
输出文件:指定要去除重复行后的内容要写入的输出文件。如果不指定此选项,则将内容显示到标准输出设备(显示终端)。

# [选项]
-c, --count    # 在每列旁边显示该行重复出现的次数;
-d, --repeated  # 仅显示重复出现的行列,即表示显示重复的行;
-u, --unique    # 只输出不重复(内容唯一)的行
-D :打印所有重复行
-i, --ignore-case :比较时忽略大小写差异
-f n ,  --skip-fields=n:忽略比较指定的栏位,前n个字段与每个字段前的空白一起被忽略;
-s <字符位置> , --skip-chars=<字符位置>:忽略比较指定的字符;
-z, --zero-terminated    # 以 NUL 空字符而非换行符作为行尾分隔符
-w <字符位置>, --check-chars=<字符位置>:指定要比较的字符。

示例演示:

代码语言:javascript
复制
# 示例0.不加参数只对相邻的行相同的内容去重
uniq file.txt
echo -e "10.0.0.1 \n 10.0.0.2 \n 10.0.0.2 \n 10.0.0.1 \n 10.0.0.1 \n 10.0.0.3 " | uniq 
#  10.0.0.1
#  10.0.0.2
#  10.0.0.1  (还是有重复)
#  10.0.0.3
uniq file.txt

# 示例1.原本使用sort输出的内容中有很多重复(实际将重复的放在一起),可在后面加上|uniq完全去重
sort file.txt | uniq
echo -e " 10.0.0.1 \n 10.0.0.2 \n 10.0.0.2 \n 10.0.0.1 \n 10.0.0.1 \n 10.0.0.3 " | sort | uniq 
#  10.0.0.1
#  10.0.0.2
#  10.0.0.3

# 示例2.按照顺序排列并且显示不重复
sort -u file #作用相同去重复
sort file | uniq -u
uniq -u file #不显示重复的数据("只显示出现一次的数据,有重复过的数据则不显示")

# 示例3.统计各行在文件中出现的次数
sort file.txt | uniq -c
echo -e " 10.0.0.1 \n 10.0.0.2 \n 10.0.0.2 \n 10.0.0.1 \n 10.0.0.1 \n 10.0.0.3 " | sort | uniq -c
# 3  10.0.0.1
# 2  10.0.0.2
# 1  10.0.0.3

# 示例4.与sort排序命令联用在文件中找出重复行
sort file.txt | uniq -d

# 示例5.统计访问登录linux服务器最多的ip
last | tr -s " " | grep "pts/0" | cut -f 1,3 -d " " | sort | uniq -c
     33 root 10.20.172.103
      1 root 192.168.228.1

# 示例6.统计并发连接最多的远程主机IP
$ ss -nt | tail -n +2 | tr -s ' ' : | cut -d ':' -f6 | sort | uniq -c | sort -nr | head -n2
      1 10.20.172.103
      1 10.100.100.5

# 示例7.取两个文件中的不同行及相同行
tee f1.txt <<EOF
A
B
1
C
EOF

tee f2.txt <<EOF
1
B
2
3
D
EOF

# 取交集
$ cat f1.txt f2.txt | sort | uniq -d
1
B

# 取差集
$ cat f1.txt f2.txt | sort | uniq -u
2
3
A
C
D

weiyigeek.top-uniq命令使用示例

fold 命令 - 文本行折叠

描述:对每个指定的文件设置自动换行(折行),并将重新排版后的结果输出到标准输出。若不指定任何文件名称,或是所给予的文件名为"-",则fold指令会从标准输入设备读取数据。

语法参数

代码语言:javascript
复制
用法:fold [选项]... [文件]...

# 参数:
-b或--bytes      # 以Byte为单位计算列宽,而非采用行数编号为单位。
-c或--characters # 以字符为单位,指定宽度
-s或--spaces     # 以空格字符作为换列点。
-w<每列行数>或--width<每列行数> # 设置每列的最大行数。

实际案例:

代码语言:javascript
复制
# 示例1.将一个 0~9 的数字文本文件( 0123456789)折叠宽度成为2。
fold -w 2 test.log
# 01
# 23
# 45
# 67
# 89

# 示例2.随机密码字符生成,并指定截取长度截取
cat /dev/urandom | tr -dc '_a-zA-Z0-9!@#$%&*.\-\+' | fold -w 12 | head -1
# yduDZvYNLY42
# .g0VvfzPooh*

truncate 命令 - 文件大小扩容或缩小

描述: 此命令可以将一个文件缩小或者扩展到某个给定的大小;

特别注意:

  • 如果指定文件不存在则创建。
  • 如果指定文件超出指定大小则超出的数据将丢失。
  • 如果指定文件小于指定大小则用 0 补足。

语法参数:

代码语言:javascript
复制
用法:truncate 选项... 文件...
#长选项必须使用的参数,对于短选项时也是必需使用的。
-c, --no-create 不创建文件
-o, --io-blocks 将SIZE 视为IO 块数而不使用字节数
-r, --reference=文件   使用此文件的大小
-s, --size=大小 使用此大小 KB 1000,K 1024,MB 1000*1000,M 1024*1024,还有 G、T、P、E、Z、Y。
    --help  显示此帮助信息并退出
    --version  显示版本信息并退出

# 指定大小也可使用以下前缀修饰:
"+" 增加,"-" 减少,"<" 至多,">" 至少,
"/" 小于等于原尺寸数字的指定数字的最小倍数,"%" 大于等于原尺寸数字的指定数字的最大倍数。
译者注:当输入值为m,参考值为n 时,
"/" 运算的数学计算式为 m / n * n;
"%" 运算的数学计算式为( m + n - 1 ) / n * n

温馨提示:参数 -r-s 是互斥的选项。

基础实例:

代码语言:javascript
复制
# 实例1.清空文件
$ truncate -s 0 /tmp/test  

# 实例2.设置文件大小与文件扩容
$ truncate -s +100M /tmp/test  
$ du -ah test  #显示真实文件的大小
0 test
$ ls -alh test #显示扩容后的文件大小
-rw-r--r--. 1 root root 100M 4月  20 22:16 test
# 例如,如果你想将文件file.txt的大小增加1GB,可以运行以下命令:
truncate -s +1G file.txt

# 实例3.参考指定文件大小进行文件扩容
$ truncate -r /etc/hosts /tmp/test
$ ls -alh /etc/hosts
  # -rw-r--r--. 1 root root 158  6月 23  2020 /etc/hosts
$ ls -alh /tmp/test
  # -rw-r--r--. 1 root root 158  6月 14 18:14 /tmp/test

# 示例4.例如,要将文件1.bin截断到1024字节而不创建新文件。
truncate -c -s 1024 1.bin
$ ls -alhg /tmp/1.bin
-rw-r--r-- 1 weiyigeek 1.0K Sep 23 09:35 /tmp/1.bin

# 示例5.将文件file.txt截断到2个块的大小
$ dd bs=16b count=1024 if=/dev/zero of=/tmp/file.txt
$ ls -alhg /tmp/file.txt
  -rw-r--r-- 1 weiyigeek 16K Sep 23 09:32 /tmp/file.txt
$ truncate -o -s 2 /tmp/1.bin
$ ls -alhg /tmp/1.bin
  # -rw-r--r-- 1 weiyigeek 8.0K Sep 23 09:34 /tmp/1.bin

split 命令 - 文件切割

描述: 此命令可以将一个大文件分割成很多个小文件,有时需要将文件分割成更小的片段,比如为提高可读性,生成日志等

语法参数:

代码语言:javascript
复制
# 语法
Usage: split [OPTION]... [FILE [PREFIX]]

# 参数
-a 生成长度为N的后缀(默认值2)
-d 使用数字而不是字母作为切割后的小文件的后缀;
-v 显示详细的处理信息
-b <字节> 每个分割文件的大小
-C <数字> 指定输出到每一个文件的每一行的大小,数字后缀可以是
    b:  512(blocks)   # 非常注意
    K:  1024(kibiBytes)
    KB: 1000(kiloBytes)
    M:  1024*1024(mebiBytes)
    MB: 1000*1000(megaBytes)
    G:  1024*1024*1024(gibiBytes)
    GB: 1000*1000*1000(gibaBytes)  #T, P, E, Z, Y
-l <行数> 指定切割的行数作为切割文件的单位;
-x 使用从0开始的十六进制后缀,而不是字母
-e 不会生成带有“-n”的空输出文件
-t 使用SEP而不是换行符作为记录分隔符;'\0'(零)指定NUL字符
-u 立即将输入复制到输出,并使用“-n r/…”

实际案例:

代码语言:javascript
复制
# 示例1.生成一个大小为100KB的测试文件,然后将其进行分割,并恢复为原始文件。
dd if=/dev/zero bs=100k count=1 of=date.file

# 使用split命令将上面创建的date.file文件分割成大小为10KB的小文件 data_split{a,b,c……}
split -b 10k date.file  data_split

# 以下是将各个块重新构建到原始文件中new_date.file
cat data_split* > new_date.file

weiyigeek.top-split分割命令的使用

代码语言:javascript
复制
# 示例2.文件被分割成多个带有字母的后缀文件,如果想用数字后缀可使用-d参数,同时可以使用-a length来指定后缀的长度:
split -b 10k date.file -d -a 3; ls 
  # date.file  x000 x001 x002 x003 x004 x005 x006 x007 x008 x009
# 为分割后的文件指定文件名的前缀以及后缀数字长度
split -b 1b anaconda-ks.cfg -d -a 2 split 
  # -rw-r--r--. 1 root root  512 Jun 26 06:33 split00
  # -rw-r--r--. 1 root root  512 Jun 26 06:33 split01
  # -rw-r--r--. 1 root root  261 Jun 26 06:33 split02
  
# 示例3.以20mb大小来分割流媒体
split -b 20m RevolutionOS.rmvb RevOS_part_ ; ls -lh
  # 总计 552M
  # -rwx------ 1 hoho hoho 276M 2005-09-09 RevolutionOS.rmvb
  # -rw-r--r-- 1 root root  20M 03-19 17:59 RevOS_part_aa
  # -rw-r--r-- 1 root root  20M 03-19 17:59 RevOS_part_ab

# 示例4.根据文件的行数来分割文件,例如把文件分割成每个包含10行的小文件:
split -l 10 f1.log
split -l 10 f1.log f1_split.log

# 示例5.按照每行1K字符串进行分割文件:
split -C 1K date.file -d -a 3 "date_split.log."
  # date_split.log.ls000
  # date_split.log.ls087

weiyigeek.top-split命令使用示例

csplit 命令 - 文件切割

描述:此命令,用于将一个大文件分割成小的碎片,并且将分割后的每个碎片保存成一个文件。碎片文件的命名类似“xx00”,“xx01”,同时每个分块文件的字节数也将被输出到标准输出。

温馨提示:csplit 命令是 split 命令的一个变体,他们的不同点是 split 只能够根据文件大小或行数来分割,而 csplit 能够根据文件本身特点来分割文件, 总体说来比 split 命令更加强大。

语法参数:

代码语言:javascript
复制
csplit [选项]... 文件or格式  #如果文件为"-",则读取标准输入
csplit [-kqsz][-b<输出格式>][-f<输出字首字符串>][-n<输出文件名位数>][文件][范本样式...] 

# 长选项必须使用的参数对于短选项时也是必需使用的:
-b, --suffix-format=FORMAT: 指定输出文件名的格式。
-f, --prefix=PREFIX: 指定输出文件名前缀,默认为xx。
-n, --digits=N: 指定输出文件名的数字位数。
-k, --keep-files: 保留在分割过程中出现错误的输出文件。
-s, --quiet: 不显示输出文件的大小信息。
-z, --elide-empty-files: 删除空的输出文件。

# 格式"可以是,一个行的偏移量需要在正整数值之后声明"+" 或 "-"
整数                不包括指定的行,并以其为文件分块边界
/表达式/[偏移量]    不包括匹配到的行,并以其为文件分块边界
%表达式%[偏移量]    预先跳过匹配的行数,以其为文件分块边界
{N} 重复指定次数的前一个模式
{*} 尽可能多地重复前面的模式

实际案例:

代码语言:javascript
复制
# 示例1.将文件 file 首个文件分割成 10 行一个文件,剩下的放在一个文件中。
$ ip addr >> ip.txt
$ csplit ip.txt 10 -f ip_csplit -b "%02d.log"
  # 544
  # 27782
 ip_csplit00.log  ip_csplit01.log 
$ wc -l ip_csplit00.log
9 ip_csplit00.log  # 实际上应该是10行,有一个换行符。

# 示例2.将 server.log 分割成 server1.log、server2.log、server3.log,这些文件的内容分别取自原文件中不同的SERVER部分,匹配 SERVER 边界每次以它作为分割界限
$ csplit server.log /SERVER/ -n2 -s {*} -f server -b "%02d.log"; rm server00.log ; 
# 把文件以字符串"Chapter X"为分界符,分成两部分 
$ csplit textfile /"Chapter X"/   
# 承上例, 但分割文件时以"Chapter X"字符串往下4行才是分割点 
$ csplit textfile /"Chapter X"/+4 

weiyigeek.top-csplit命令按文件内容分割

代码语言:javascript
复制
# 示例3.按行分割
csplit test.txt -z -f server -b "%02d.log" 6 {1}    # 6 line 需要除去 \n一行,分成3份 (自动匹配分割可能会出错)
# 93
# 102
# 87

# 示例4.把文件 FILE 分解,分解后大小为 15000 行,文件名前缀为 prefix 后缀为 00、01、02 ......99,而文件个数不多于100个。 
csplit -k -f prefix FILE 15000 {99}  

# 示例5.匹配包含weiygeek.top的行,输出文件名使用wy+两位数字,即输出文件名格式为sm00.log、sm01.log等。
$ csplit m2.txt /weiygeek.top/ -n2 -f sm -b "%02d.log"

特别注意:您可以使用星号通配符来告诉 csplit 尽可能多地重复分割。这听起来很酷,但是如果文件不能等分,则可能会失败

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈工程师修炼指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 Linux 文本分割排序命令
    • cut 命令 - 提取部分文本内容
      • tr 命令 - 转换或删除文件中的字符
        • paste 命令 - 文件行合并
          • sort 命令 - 文件内容排序
            • uniq 命令 - 文件文本去重
              • fold 命令 - 文本行折叠
                • truncate 命令 - 文件大小扩容或缩小
                  • split 命令 - 文件切割
                    • csplit 命令 - 文件切割
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档