sftp

upload local file to remote sftp:

1
sftp -oPort=2201 user@host:${remote_path} <<< $'put {local_file_path}'

download remote file to local:

1
sftp user@host:${remote_path} ${local_path}

路径支持通配符来匹配多个文件

sftp常用命令有这些:ls ls -lh rm put get等。

split

  • mac安装gsplit: brew install coreutils

文件分割比较有用。例如把一个script.sql文件按每100行拆分,输出文件前缀为split_
mac上用的gsplit (GNU版本的split)

1
gsplit -dl 400 --additional-suffix=.sql script.sql script_

也支持按文件大小分割,同时支持按行分割

1
gsplit -C 10M --additional-suffix=.sql script.sql script_

sed

例如,script.sql文件每行一条insert语句,想要改成on duplicate update来同时支持插入和已有记录的更新(这个操作是幂等的),就可以用下面的方法:

第一步,去掉文件每行末的最后一个字符:

1
sed 's/.$//' script.sql > script_noprefix.sql

然后,给每行加上指定字符串,这里是ON DUPLICATE KEY:

1
sed 's/.$/ ON DUPLICATE KEY UPDATE update_time=values(update_time);/' script_noprefix.sql > script_update_insert.sql

sed支持直接替换,上面的例子也可以直接替最后一个字符为指定字符串。
一个替换的例子(mac版本),注意:这里是原地替换,直接修改原文件内

1
sed -i '' -- 's/.$/ ON DUPLICATE KEY UPDATE update_time=values(update_time);/g' script.sql

awk 实用套路

其他学习文章

匹配

包含某些关键词,但不包含其他关键词

1
awk -F '|' '/error|warn/ && !/system/' error.log

统计

日志第一列是ip,数不同ip的日志行数

1
awk -v OFS='\t' -F '|' '{count[$1]++;} END {for (ip in count) print ip, count[ip]}' info.log

按照ip数统计某个url的请求量

1
awk -F '|' '/api\/service/ && !/api\/service\/other/ {c[$1]++} END {for (ip in c) print ip,c[ip]}' info.log

按照小时统计某个url的请求量

sample log

1
0.0.0.0|2019-12-19 13:01:02|elapsed=12ms,url=/api/service
1
awk -F '|' '/api\/service/ {split($2, t, "[-: ]"); c[t[4]]++;} END {for (hour in c) print hour,c[hour]}' info.log | sort -k1

按照小时统计某个url的请求量,并且包含占总量的百分比

1
awk -F '|' '/api\/service/ {split($2, t, "[-: ]"); c[t[4]]++; s++} END {for (hour in c) printf "%s\t%s\t%.2f\n" hour,c[hour],100*c[hour]/s}' info.log | sort -k1

统计错误日志中不同类型的种类

1
awk -F '|' ' /ERROR/ {c[$7]++;s++} END {for (r in c) printf "%s\t%.2f\t%s\n", c[r],100*c[r]/s,r}' error.log | sort -k2

连接状态统计

1
ss | awk 'NR!=1{c[$2]++} END {for (s in c) print s, c[s]}'

统计不同目的ip的不同状态的连接数

1
netstat -t | awk -v OFS='\t\t' 'NR>2{c[$5,$6]++} END {for (x in c) {split(x, s, SUBSEP); print c[x],s[2],s[1]} }'

远程awk重定向输出到本地文件

这个需要在本地分析日志时很有用,heredoc可以避开escape的问题。

借助heredoc和ssh重定向

1
2
3
ssh > daemon.log aps-live-log <<-'EOF'
awk -F '|' '!/ktc_settlement_report/ && !/txn_3ds/ && $2>"[2020-01-05 01:00:00" && $2<"[2020-01-05 01:05:00"' /data/error.log
EOF

awk 正则匹配筛选比较耗时的请求

正则匹配提取:

1
awk -F'|' 'match($6, /elapsed=([0-9]+)/, ta) && match($6, /id=([0-9]+)/, ka) {c[ka[1]]=ta[1]} END {for (k in c) {print t,c[t]}}' data.log | sort -n -k 2

数值比较(筛选出耗时超过2秒的请求)

1
awk -F'|' 'match($6, /elapsed=([0-9]+)/, ta) && match($6, /id=([0-9]+)/, ka) {if ((ta[1]+0)>2000) c[ka[1]]=ta[1]} END {for (t in c) {print t,c[t]}}' data_log | sort -n -k 2