1.sed流编辑器简介
- 一次从输入中读取一行数据。
- 根据所提供的编辑器命令匹配数据。
- 按照命令修改流中的数据。
- 将新的数据输出到 STDOUT
格式:sed options script file
举例:
1.sed -e 's/brown/green/; s/dog/cat/' data1.txt
2.sed -f script1.sed data1.txt
2.gawk程序简介
- 定义变量来保存数据;
- 使用算术和字符串操作符来处理数据;
- 使用结构化编程概念(比如 if-then 语句和循环)来为数据处理增加处理逻辑;
- 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告
格式:gawk options program file
- $0 代表整个文本行;
- $1 代表文本行中的第1个数据字段;
- $2 代表文本行中的第2个数据字段;
- $n 代表文本行中的第n个数据字段。
举例:
1.gawk '{print $1}' data2.txt
2.指定分隔符:gawk -F: '{print $1}' /etc/passwd
3.echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
4.从文件中读取命令:gawk -F: -f script2.gawk /etc/passwd
5.处理数据前运行脚本:gawk 'BEGIN {print "Hello World!"}'
3.sed 编辑器基础
-
1.替换标记
- 数字,表明新文本将替换第几处模式匹配的地方;
- g ,表明新文本将会替换所有匹配的文本;
- p ,表明原先行的内容要打印出来;
- w file ,将替换的结果写到文件中
sed 's/test/trial/2' data4.txt sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd sed 's!/bin/bash!/bin/csh!' /etc/passwd #可用感叹号作字符串分隔符
- 2.使用地址
- 以数字形式表示行区间
- 用文本模式来过滤出行
格式:
[address]command
/pattern/command
举例:
sed '2,$s/dog/cat/' data1.txt #从第2行开始的所有行
sed '/Samantha/s/bash/csh/' /etc/passwd #只修改用户Samantha的默认shell
- 3.删除行
举例
sed '3d' data6.txt #删除第三行
sed '3,$d' data6.txt #删除第3行到最后一行
sed '/number 1/d' data6.txt #删除包含number 1的行
sed '/1/,/3/d' data6.txt #这里1是开启删除的模式(出现数字1的行),3是停止模式(出现数字3的行)
- 4.插入和附加文本
举例:
echo "Line 2" | sed '1i\Line 1' #第一行前加一行
echo "Line 2" | sed '$a\Line 1' #最后一行后加一行
- 5.修改行
sed '3c\This is a changed line of text.' data6.txt #修改第三行
sed '/number 3/c\This is a changed line of text.' data6.txt #同上
sed '2,3c\This is a new line of text.' data6.txt #替换第2,3行
- 6.转换命令
格式:[address]y/inchars/outchars/
举例:
echo "This 1 is a test of 1 try." | sed 'y/123/456/'
- 7.再说打印
- p 命令用来打印文本行;
- 等号( = )命令用来打印行号;
- l (小写的L)命令用来列出行
举例
sed -n '/number 3/p' data6.txt # -n 选项禁止输出其他行
sed -n '2,3p' data6.txt
sed '=' data1.txt #打印行号
sed -n 'l' data6.txt #显示不可打印字符,如\t\r
- 8.处理文件
sed '1,2w test.txt' data6.txt #将1,2行打印到文件test.txt
sed -n '/hzq/w hzq.txt' data11.txt #将包含hzq的行打印进hzq.txt
sed '$r data12.txt' data6.txt #在文件末尾插入文件date12.txt的内容
sed '/LIST/{ #查找展位字符串LIST
r data11.txt #替换为data11.txt的内容
d #删除占位行
}' notice.std
shell编程题
来源:领扣网络
- 1、写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。
#方式1
cat words.txt | sed 's/[ ][ ]*/\n/g' | egrep -v "^$"|sort | uniq -c | sort -nr | awk '{print $NF,$1}'
#方式2
cat words.txt | xargs | sed ':a; s/ /\n/;t a;'| sort | uniq -c | sort -r | awk '{print $2,$1}'
#方式3
cat words.txt | (while read line;do for word in $line;do echo $word;done;done)| sort | uniq -c | sort -k1nr | awk '{print $2 " " $1}'
-
2、给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个 bash 脚本输出所有有效的电话号码。你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)你也可以假设每行前后没有多余的空格字符。假设 file.txt 内容如下:
987-123-4567 123 456 7890 (123) 456-7890
你的脚本应当输出下列有效的电话号码:
987-123-4567
(123) 456-7890
#方式1
grep -P "^(\d{3}-|(\d{3})\s)\d{3}-\d{4}$" file.txt
#方式2
awk '/^([0-9]{3}-|([0-9]{3}) )[0-9]{3}-([0-9]{4})$/' file.txt
#方式3
sed -n -r '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/p' file.txt
#方式4
while read line
do
if [[ $line =~ ^((\([0-9]{3}\) )|([0-9]{3}-))[0-9]{3}-[0-9]{4}$ ]]; then
echo $line
fi
done < file.txt
-
3、给定一个文件 file.txt,转置它的内容。你可以假设每行列数相同,并且每个字段由 ’ ’ 分隔。示例:(假设 file.txt 文件内容如下:)
name age alice 21 ryan 30
应当输出:
name alice ryan
age 21 30
#方式1
awk '{ for(i=1;i<=NF;i++){ if(NR == 1){ a[i] = i; } else { a[i] = a[i]" "i; } } }END{ for(i=1;i<=NF;i++){ print a[i]; } }' file.txt
#方式1排了下板
awk '{ #这个大括号里的代码是 对正文的处理
# NF表示列数,NR表示已读的行数
# 注意for中的i从1开始,i前没有类型
for (i=1; i<=NF; i++){#对每一列
if(NR==1){ #如果是第一行
#将第i列的值存入res[i],$i表示第i列的值,i为数组的下标,以列序号为下标,
#数组不用定义可以直接使用
res[i]=$i;
}
else{
#不是第一行时,将该行对应i列的值拼接到res[i]
res[i]=res[i] " " $i
}
}
}
# BEGIN{} 文件进行扫描前要执行的操作;END{} 文件扫描结束后要执行的操作。
END{
#输出数组
for (i=1; i<=NF; i++){
print res[i]
}
}' file.txt
#方式2
awk '{for(i=1;i<=NR;i++){if(NF>m){m=NF}}for(i=1;i<=m;i++){if(NR==1){a[i]=$i}else{a[i]=a[i]" "$i}}}END{for(i=1;a[i]!="";i++){print a[i]}}' file.txt
#方式3 (常规)
awk -F' ' '{for(i=1; i <= NF; ++i){line[i] = line[i] " " $i;}}END{for(n in line){print substr(line[n],2);}} ' file.txt