文档章节

shell脚本-----按行读取文件

 蜗牛奔跑
发布于 2015/06/18 15:06
字数 3673
阅读 74
收藏 0
点赞 0
评论 0

shell脚本-----按行读取文件

分类: Shell脚本2013-06-30 20:26 7300人阅读 评论(0) 收藏 举报

按行读取文件

[cpp] view plaincopyprint?

  1. #!/bin/bash  

  2.   

  3. echo "##### 方法 1 #####"  

  4. while read line1  

  5. do  

  6.     echo $line1  

  7. done < $1  

  8.   

  9. echo "##### 方法 2 #####"  

  10. cat $1 | while read line2  

  11. do  

  12.     echo $line2  

  13. done  

  14.   

  15. echo "##### 方法 3 #####"  

  16. for line3 in $(<$1)  

  17. do  

  18.     echo $line3  

  19. done  


运行结果

snail@ubuntu:5.read-line$ cat file.bin 
hello world
this is 1
this is 2
this is 3
snail@ubuntu:5.read-line$ ./read-line.sh file.bin 
##### 方法 1 #####
hello world
this is 1
this is 2
this is 3
##### 方法 2 #####
hello world
this is 1
this is 2
this is 3
##### 方法 3 #####
hello
world
this
is
1
this
is
2
this
is
3

使用for读取时,自动按空格作为间隔符。

如果输入文本每行中没有空格,则line在输入文本中按换行符分隔符循环取值.

如果输入文本中包括空格或制表符,则不是换行读取,line在输入文本中按空格分隔符或制表符或换行符特环取值.

可以通过把IFS设置为换行符来达到逐行读取的功能.

[cpp] view plaincopyprint?

  1. IFS=$'\n'  

  2.   

  3. echo "##### 方法 3 #####"  

  4. for line3 in $(<$1)  

  5. do  

  6.     echo $line3  

  7. done  



hello world!
#! /bin/bash
echo “hello world!”

$ chmod +x a.sh
$ ./a.sh
hello world!



变量
变量不分类型 (没有int,char,string)
不需要声明,直接使用
赋值:name=value (左右两边不能有空格)
使用:$name ${name}


foo=h
echo ${foo}ello


变量的作用域
默认全局作用域(仅当前shell可见)
local 限定函数局部变量
function a() { local msg; }
使用export导出变量,让子shell可以继承
export var=1
source 或 .(dot) 在当前shell下执行脚本
source ./config.sh


变量分类
自定义变量
环境变量 (set命名可查看)
$PATH,$IFS,$PS1,$PWD,$LINENO
位置参数(Positional Parameters)
$1 $2 $3 … ${10}
特殊参数(Special Parameters)
$#:位置参数的数量 
$*:所有位置参数的内容 ($1 $2 …)
$@: 所有位置参数的内容(“$1” “$2” … )
$?:命令执行后返回的状态
$$:当前进程的进程号 
$!:后台运行的最后一个进程号
$0:当前执行的进程名


玩转变量
使用eval实现变量的间接引用
x='abc def'
y='$x'
echo $y
$x
eval echo $y
abc de




玩转变量(续)
${!p} #双重引用
a=1
b='a'
echo ${!b}
1
${!p*} #返回所有以p开头的变量 
echo ${!P*}
PATH PIPESTATUS PPID PS1 PS2 PS4 PWD
${p:-word} #如果变量p不存在,返回"word”
${p:=word} #如果变量p不存在,返回"word",并将p的值设为"word"
${p:?word} #如果变量p不存在,将"word"打入STDERR 
${p:+word} #如果变量p存在,返回"word" 


玩转变量(续)
if [${ret:=1} -ne 0 ]
then
echo “NO”
exit
fi



引号迷雾
双引号

使用双引号可解释$符号,反引号和反斜线等特殊字符
echo “$msg” => 显示msg变量值
单引号
与双引号类似,不同的是shell会忽略任何特殊符号
echo ‘$msg’ => 显示$msg 
反斜杆
\c == ‘c’
反引号(命令替换) 
用于执行系统命令并输出到变量
echo The date and time is `date`  


几种括号
(list) list将在一个子shell中执行, 不会对当前shell产生影响,返回list的exit值
{ list; } 可以作组合命令用,list将在当前shell中被执行,list结尾处必须要有新行或‘;’号,返回list的exit值,list前后必须有空格 
((expression)) 算术计算 
[ ] [[ ]] 分支测试


数组
name=(value1 ... valuen) 此时下标从0开始
name[index]=value
unset name 或 name=

数组下标的范围没有任何限制,同时也不必使用连续的分量
$ A=(a b c def)
$ A[3]=bb

$ echo ${A[0]} #取第一个元素
a
$ echo ${A[@]} # 取全部元素
a b c def
$ echo ${#A[@]} # 取得数组元素的个数




数组(续)
遍历数组:
total=${#A[*]}
for ((i = 0; i < total; i++))
do
echo ${A[$i]}
done



分支语句
if list; then command; 
[ elif list; then command; ] ... 
[ else command; ]
fi
case $word in
[a-z]) list ;;
*) default;;
esac
[ $# -eq 1 ] && slen=1 || slen=0



条件测试
对文件、字符串和数字使用test命令。test一般有两种格式:
test condition 或 [ condition ](注意空格)
if [ $str = “a.txt” ];then 
echo “OK"
fi
直接测试命令:
if grep abc a.txt &>/dev/null;then
echo “Bingo!”
fi




条件测试(续)
推荐使用[[ ]]进行条件测试
if [[ “x$str”== “xa.txt” && -f b.txt ]]
then
cmd;
fi
-f -d -z ……
man bash
CONDITIONAL EXPRESSIONS



条件测试 – 数值比较
if [ $a –lt 0 ]
then
echo OK
fi

推荐使用(( ))
if (( a > 0 ))
then
echo OK
fi



循环语句
for name [ in word ] ; do list ; done
for i in `ls *.result`;do cat $i; done

for (( expr1 ; expr2 ; expr3 )) ; do list ;done
for ((i=0;i<100;i++));do echo $i;done

while list; do list; done
while read line
do
echo $line
done < a.txt
until list; do list; done



注释
# 行注释 (#前要有空格)
echo $msg #print message

块注释
:<<COMMENT
echo $msg
COMMENT

comment()
{
echo $msg
}


正则表达式基础
元字符
. 匹配任何单个字符。
 $ 匹配行结束符。^ 匹配一行的开始。
* 匹配0或多个正好在它之前的那个字符。
+ 匹配1或多个正好在它之前的那个字符。
? 匹配0或1个正好在它之前的那个字符。
\{i\} \{i,j\} 匹配指定数目的字符。
\ 这是引用符,转义;
[ ]  [c1-c2] 匹配括号中的任何一个字符。 [^c1-c2] 
\< \> 匹配词(word)的开始(\<)和结束(\>)。
 将  之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
| 将 两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 



正则表达式举例
HTML标签
<[^>]*> 

匹配由26个英文字母组成的字符串 
^[A-Za-z]+$
  
Email地址
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 

URL
[a-zA-z]+://[^\s]*



管道和重定向
管道可以把一条命令的输出作为另一条命令的输入
Command1 | Command2
返回值是最后一个命令的返回值

重定向
wc –l /etc/passwd > a.txt
wc –l /etc/passwd >> a.txt
wc –l < /etc/passwd
./command > a.txt 2>&1 (./command &> a.txt)

exec 5<> a.txt
echo “hello” >&5
<&- 
>&-


作业控制
<CTRL-Z> 将当前任务挂起,返回job_id
fg job_id 把后台作业放到前台执行
bg job_id 把作业放到后台执行

vi b.sh
<CTRL-Z>
[1]+ Stopped vim b.sh
bg 1
[1]+ vim b.sh &
fg 1
vim b.sh


自定义函数
function foo() # foo为函数名
{
local a=$1; # 局部变量

echo $a;
return 0; # 返回值
}

foo “cool!” # 函数调用
echo $? # 打印返回值



自定义函数 – 16进制转点分十进制
a()
{
       local str=$1
       echo -n $((16#${str:0:2}))
       str=${str:2}
       if [ "x$str" = "x" ]
       then
              echo; return
       else
              echo -n "."; a $str
       fi
}
#Usage
a "DDB14CCF"


整数计算
id++ id-- ++id –id - + ! ~ ** * / % 计算
<< >> & ^ | 位操作
<= >= < > == != 比较
&& || 逻辑操作
expr?expr:expr 三元操作符
= *= /= %= += -= <<= >>= &= ^= |= 赋值操作符

y=2000 闰年计算
echo  $((y%4==0 && y%100!=0 || y%400==0)) 
(( y++ )) 自增1
tmp=$((16#a)) 进制转换


浮点运算
echo “scale=5; 3/7"|bc –l
.42857
echo "100.43KB 20.12KB" | awk '{print $1-$2}'
80.31
echo "ibase=16;F"|bc -l 
15




简单字符串处理
x=abcd
${#x} # 获取字串长度
4
expr index  $x “b“ # 获取子串所在偏移
2expr index  $x "a“ # 获取子串所在偏移

echo ${x:1} # 获取子串
bcdecho ${x:2}cdecho ${x:0:2} 
ab



简单的字符串处理(续)
x=aabbaarealwwvvwwecho “${x%w*w}“ # 截去尾部最短匹配
aabbaarealwwvvecho “${x%%w*w}“ # 截去尾部最长匹配
aabbaarealecho “${x##a*a}“ # 截去头部最长匹配
lwwvvwwecho “${x#a*a}“ # 截去头部最短匹配
bbaarealwwvvww 

x=abcdabcdecho ${x/a/b} # 只替换一个bbcdabcdecho ${x//a/b} # 替换所有bbcdbbcd


简单字符串处理 – 实际应用
截去域名尾部
name=jx-sys-superdb.jx.baidu.com
echo ${name%%.*} 
jx-sys-superdb

截取日期
str=20081011
year=${str:0:4} 

替换
echo ${name//jx/tc}
tc-sys-superdb.tc.baidu.com


随机字符串生成
typeset -r DEFAULT_STR_LEN=5
typeset -ra dict=(a b c d e f g h i j k l m n o p q r s t u v w x y z)

function get_random_letter()
{
echo -n ${dict[$((RANDOM%${#dict[*]}))]}
return 0
}

function get_random_string()
{
local slen str

[ $# -eq 1 ] && slen=$1 || slen=$DEFAULT_STR_LEN

for ((i = 0; i < slen; i++))
do
str=${str}`get_random_letter`
done

echo $str
return 0
}

get_random_string $1


调试
-x
-n 是只语法检查而不执行任何命令
-e 是脚本发生第一个错误时就中止脚本运行,即当一个命令返回非零值时退出脚本 (除了until 或 while loops, if-tests, list constructs)
--posix 是更改Bash或脚本的行为,使之符合POSIX标准
Shell 伪信号:EXIT,ERR,DEBUG


调试(续)
+ typeset -r DEFAULT_STR_LEN=5
+ typeset -ra 'dict=(a b c d e f g h i j k l m n o p q r s t u v w x y z)'
+ get_random_string 2
+ local slen str
+ '[' 1 -eq 1 ']'
+ slen=2
+ (( i = 0 ))
+ (( i < slen ))
++ get_random_letter
++ echo -n t
++ return 0
+ str=t
+ (( i++ ))
+ (( i < slen ))
++ get_random_letter
++ echo -n k
++ return 0
+ str=tk
+ (( i++ ))
+ (( i < slen ))
+ echo tk
tk
+ return 0

信号捕获
#!/bin/bash

trap "print_OK" 3

function print_OK()
{
echo OK
}

while :
do
:
done

发送信号:kill -3 pid

屏蔽信号:trap “” 3


其他常用内置命令
exec command #用command替换当前进程
type ls
ls is aliased to `ls --color=tty`
: 空命令
while :
do
cmd
done

if [ list ]; then : ;else echo false;fi


常用工具
编辑软件: vi,emacs
联机帮助:man, info
查找类:find,locate,which,whereis,whatis
文本处理类:uniq,cut,paste,join,sort,comm,diff
二进制文件读取类:od,xxd,dd,hexdump
文本分析类:grep,sed,awk
系统状态类:top,ps,pstree,pgrep,/proc,strace,vmstat,netstat
传输类:wget



Grep - 全文匹配利器
--color 飘红匹配到的部分
-i 忽略大小写
-v 反向匹配
-r 递归匹配文件
-o 只打印匹配到的部分
-n 打印出行号
-c 统计匹配到的行数
-w 匹配整词

grep "sort“ *.doc 

Awk – 文本处理利器
awk命令的一般形式: awk ' BEGIN { actions } pattern1 { actions } ............ patternN { actions } END { actions } ‘
awk -F: '{print $1} END{print "total:",NR}' /etc/passwd 



Awk – 文本处理利器 (续)
取机器序列号
dmidecode|awk '/Serial Number:/{print $NF;exit}‘

统计词频
awk '{a[$0]++}END{for(i in a){print i,a[i]}}' a.txt

类似uniq功能
awk '! a[$0]++' a.txt



Awk – 文本处理利器 (续)
杨辉三角
#!/usr/bin/awk -fBEGIN {         yan[1,0] = 1;         for (i = 2; i <= int(ARGV[1]); i++)         {                 yan[i,0] = 1;                 yan[i,i-1] = 1;                                 for (j = i-2; j > 0; j--)                         yan[i,j] = yan[i-1,j-1] + yan[i-1,j]         }                 # output         for (i = 1; i <= int(ARGV[1]); i++)         {                 for (j = 0; j < i; j++)                         printf("%d ", yan[i,j]);                 print         }}
#Usage:
#     $ ./test.awk 10


head,tail
功能:取一个文件的头若干行或者尾部的若干行。
常用选项:
-n num:指定选取的行数
-f:tail的选项,定时输出文件的最后若干行。
使用举例
tail和head常用来分析日志或者对大规模数据抽取一小部分
tail –f example.log
watch -n 1 head url.lst 



diff,cmp,diff3,sdiff,comm
功能:
diff:按行比较两个文件的不同
cmp:按字节比较两个文件的不同
diff3:按行比较三个文件的不同
sdiff:输出两个文件的合集。输出文件中两个文件原本的行在同一行中不同列
comm:快速的比较两个已经排过序的文件,输出两个文件的合集,交集,或任何单独的部分



diff常用选项
常用选项。主要介绍diff的各个选项
-b 忽略两行行尾空格,以及空格个数的区别
-E 忽略tab和空格间的区别
-w 完全忽略所有空格类字符
-B 忽略空行
-I 忽略大小写
--normal以normal形式输出不同行。即指输出不同的行
-c 以context形式输出不同行。包含不同行的上下文



find,locate
功能:查找文件。find将在目录树中查找和用户指定模式相符合的文件。locate则是通过在locate的数据库中查找,locate 的数据库由updatedb程序负责维护。
常用选项:
-name:指定要查找的文件名
-perm:指定要查找文件的权限
-size:指定要查找文件的大小范围
-mtime:指定查找修改时间在n天以内的文件。
exec command:将find命令查找到的文件作为command命令的参数
使用举例:
find . -mtime –1:查找在最近一天内被修改的文件
find . -name b.cpp -exec mv \{\} a.cpp \;





sort
功能:对文件中的各行进行排序。
sort排序是根据从输入行抽取的一个或多个关键字进行比较来完成的。缺省情况下以整行为关键字按ASCII字符顺序进行排序。
常用选项
- m 若给定文件已排好序,合并文件。
- c 检查给定文件是否已排好序。
- u 对排序后认为相同的行只留其中一行。
- d 按字典顺序排序,仅比较字母、数字、空格和制表符。
- r 按逆序输出排序结果。
- b 在每行中寻找排序关键字时忽略前导的空格和制表符。
- t separator 指定字符separator作为字段分隔符。
-k,pos1,[pos2]:以pos1到pos2中间的字符为键值
使用举例
cat words | uniq –c | sort –k 1,1 –n –r 将一批词按照出现频次有高到低排序



uniq,join,cut,paste
cut功能:用来从标准输入或文本中剪切指定列或者域
常用选项:
-c:指定剪切字符数
-f:field 指定剪切指定域数
-d:delimit 指定除空格和tab外的域分隔符
使用举例:
cut –d : -f 3 example.txt
who –u|cut –c1-8
paste功能:将两个文件按行粘贴在不同的列中。是cut的反向操作。



dd
拷贝二进制文件,
格式:
count=BLOCKS 只拷贝BLOCKS个数据块
ibs=BYTES 一次读入的数据量
if=FILE 输入文件
obs=BYTES 一次写出的数据量
of=FILE 输出文件
seek=BLOCKS 输出文件跳过BLOCKS个数据块
skip=BLOCKS 输入文件跳过BLOCKS个数据块

time dd if=/dev/zero of=test bs=1024k count=1024 查看系统io性能


wget
功能:支持使用FTP和HTTP协议,从其他主机上下载所需要的文件
常用选项:
-r:递归的下载目录以及它的子目录和所有文件
-nH:不创建以目标主机域名为目录名的目录,将目标主机的目录结构直接下到当前目录下
--cut-dir=[number]不在本地机器上建立的目录层数
-m, --mirror自动开启适合用来镜像站点的选项 
-A, --accept=LIST允许下载的文件类型列表
-R, --reject=LIST拒绝继续下载的文件类型列表
-D, --domains=LIST允许继续扩展的站点列表
--tries=[number]自动重连的次数 
-c:断点续传 
--debug:使用这个选项可以看到更多wget下载文件过程中的调试信息,比如下载一个http文件时所发送和接收的http包头的格式
--timeout=SECONDS控制wget读超时时间,缺省为900秒
Wget –nH –cut-dir=1 ftp://*:*@test.baidu.com/
wget “http://www.sina.com”




参考资料
Man
正则表达式之道
Sed与awk
Advanced Bash-Scripting Guide

本文转载自:

共有 人打赏支持
粉丝 34
博文 596
码字总数 114025
作品 0
海淀
Using the Python Interpret 之 Invoking the Interp

一,启动(invoking)python解释器 python解释器通常情况下如果你的机器允许的话会安装在 /usr/local/bin/python 目录下,然后你需要把这个路径放置到系统的环境变量中并且确保它生效,然后你...

Koma ⋅ 2015/02/28 ⋅ 6

大神教你如何在 Linux 中启用 Shell 脚本的调试模式

导读 脚本是存储在一个文件的一系列命令。在终端上输入一个个命令,按顺序执行的方法太弱了,使用脚本,系统中的用户可以在一个文件中存储所有命令,反复调用该文件多次重新执行命令。 在学习...

linux小陶 ⋅ 2016/12/20 ⋅ 0

Linux Shell 文本处理工具集锦

Linux Shell 文本处理工具集锦 本文将介绍Linux下使用Shell处理文本时最常用的工具: find、grep、xargs、sort、uniq、tr、cut、paste、wc、sed、awk; 提供的例子和参数都是最常用和最为实用...

平凡之路 ⋅ 2014/10/13 ⋅ 0

Linux BASH多进程并行处理的方法实现

在shell中进行多进程处理,以前写的都是单进程的,今天看了一篇文章讲了linux的多进程处理。 多进程的实现,主要有两点 1、将当前的进程放到后台去执行,要用到& 2、在shell脚本的最后面加上...

sucre ⋅ 2016/06/08 ⋅ 0

【Linux学习】之 Shell初识

Shell 的 历史: - 1977年 Bourne Shell发布,并作为UNIX 7的默认Shell。 - 由于BourneShell 一直没有正式的版本号且交互性不好, 加州大学伯克利分校的一名学生编写了 C Shell,由于不支持正...

fanfan4569 ⋅ 2017/11/16 ⋅ 0

常用shell脚本

1、脚本之间传递参数 "1.sh"的脚本,接受参数。如下,如果有一个参数则赋值个sourceFile这个变量,否则用默认值。 Shell代码 #!/bin/bash LANG=enUS.UTF-8 #get parameters sourceFile="/dat...

蓝狐乐队 ⋅ 2015/04/09 ⋅ 0

初识sed与gawk

博文阅读 学习内容: 学习sed编辑器 gawk编辑器入门 sed编辑器基础 shell脚本最常见的一个用途就是处理文本文件,但仅靠shell脚本命令来处理文本文件的内容有点勉为其难。如果我们想在shell...

王诗翔 ⋅ 2017/12/26 ⋅ 0

Linux shell篇---之一--shell基础

一、shell基础 1、shell的基本概念 shell就是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。 用户界面shell(还有其他用户界面如kde等图形界面)-->内核--》硬件。 2、shell...

kuang_hp ⋅ 2015/08/26 ⋅ 0

Linux Shell处理文本最常用的工具大盘点

导读 本文将介绍Linux下使用Shell处理文本时最常用的工具:find、grep、xargs、sort、uniq、tr、cut、paste、wc、sed、awk;提供的例子和参数都是最常用和最为实用的,我对shell脚本使用的原...

linuxprobe16 ⋅ 2016/12/21 ⋅ 0

用shell脚本监控进程是否存在 不存在则启动的实例

用shell脚本监控进程是否存在 不存在则启动的实例 用shell脚本监控进程是否存在 不存在则启动的实例,先上代码干货: #!/bin/shps -fe|grep processString |grep -v grepif [ $? -ne 0 ]the...

xiaozhenkai ⋅ 2017/07/31 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

tcp/ip详解-链路层

简介 设计链路层的目的: 为IP模块发送和接收IP数据报 为ARP模块发送ARP请求和接收ARP应答 为RARP模块发送RARP请求和接收RARP应答 TCP/IP支持多种链路层协议,如以太网、令牌环往、FDDI、RS-...

loda0128 ⋅ 58分钟前 ⋅ 0

spring.net aop代码例子

https://www.cnblogs.com/haogj/archive/2011/10/12/2207916.html

whoisliang ⋅ 今天 ⋅ 0

发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信 场景: 发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信. 如何实现呢? 思路有两个 截至到当...

黄威 ⋅ 昨天 ⋅ 0

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 昨天 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 昨天 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 昨天 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 昨天 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

SpringBoot简单使用ehcache

1,SpringBoot版本 2.0.3.RELEASE ①,pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELE......

暗中观察 ⋅ 昨天 ⋅ 0

Spring源码解析(八)——实例创建(下)

前言 来到实例创建的最后一节,前面已经将一个实例通过不同方式(工厂方法、构造器注入、默认构造器)给创建出来了,下面我们要对创建出来的实例进行一些“加工”处理。 源码解读 回顾下之前...

MarvelCode ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部