常用shell

工作中经常遇到的shell整理如下:

1.shell脚本传入时间参数并判断

#! /bin/bash
echo "[-DEBUG-] Start <$0>"
start_running_time=`date +%s`

if [ $# = 1 ]
then
start_dt=$1
end_dt=$1
elif [ $# = 2 ]
then
start_dt=$1
end_dt=$2
elif [ $# = 0 ]
then
start_dt=`date -d '-1 day' +%F`
end_dt=`date -d '-1 day' +%F`
fi

start_sec=`date -d $start_dt +%s`
end_sec=`date -d $end_dt +%s`
for ((i=$start_sec;i<=$end_sec;i+=86400))
do

partition_pt=`date -d @$i +%F`
partition_hour=`date -d @$i +%Y.%m.%d.%H`
start_hour_of_day=`date -d @$i +%Y.%m.%d.00`
end_hour_of_day=`date -d @$i +%Y.%m.%d.23`
yesterday_date=`date -d $partition_pt'-1 day' +%F`

done

2.查找文件并拷贝

find /export/home/pp_adm/sql -name "*.sql" | xargs -i cp {}  ./
# linux
find . -name "load_olap*.sh.job" -type f | xargs -i cp {} /Users/xieyin/Downloads/My_test
# MacOS
find /Users/xieyin/Downloads/im_stats -name "load_olap*.sh.job" -type f | xargs -I F cp "F" /Users/xieyin/Downloads/My_test

3.删除包含指定字符串的行

sed -i '/dependencies=/d' load_olap*.sh.job

4.时间戳转换为时间格式

1598835492918 # 13位毫秒
date -d @1598835492.918 "+%Y-%m-%d %H:%M:%S" # 先转换成秒: 2020-08-31 08:58:12
date +%s # 秒: 1598843957 
date -d @1598843957 "+%Y-%m-%d %H:%M:%S" # 转换成时间: 2020-08-31 11:19:17

5.获取时间戳(纳秒)

echo $[$(date +%s%N)]

6.获取时间戳(毫秒)

echo $[$(date +%s%N)/1000000]

7.转换为秒

start_sec=`expr 1598835492918/1000`
end_sec=`expr 1598844141960/1000`
duration_sec=`expr 1598844141960 - 1598835492918`

start_s=1598835492918
end_s=1598844141960
dura=$(($end_s-$start_s)) # 8649042
mins=$(($dura/1000/60))

8.grep精确匹配

line=olap_ch.warehouse_check
isFound=$(grep -i "\<$line\>" migration_01.lst)

b='abc(edg)ad(fi)rpqu'
echo $b|grep -o '(.*)'

9.获取文件大小

`ls -l filename | awk ‘{print $5}’`

10.只删除纯空行

sed '/^\s*$/d' file

11.删除纯空行和由空格组成的空行

sed '/^[  ]*$/d' file

12.hive 替换制表符、换行符

select regexp_replace('\t abc \n def \r hij', '\n|\t|\r', '');

13.判断上一个命令的执行结果

RC=$?
if [ $RC -eq 0 ];then
    echo "Loading into clickhouse succeed!"
else
    echo "Loading into clickhouse failed!"
    exit 1
fi

14.替换

sed -i 's/zx_clickhouse/zx_temp/g' *.job

# 将 string 中第一个 match_string 替换成 replace_string
${string/#match_string/replace_string}
# 将 string 中的 match_string 全部替换成 replace_string
${string/%match_string/replace_string}

15.awk中引用shell变量

# 其实在awk里,是不能直接使用shell变量的
# 方法是:awk -v 选项让awk 里使用shell变量
TIME=60
awk -v time="$TIME" 'BEGIN{FS="|"} {if ($7>time) print $2 }'
# 这样要注意:在awk里,time不能加$符号。

16.判断文件大小是否为0

filename=/data/clickhouse/dump/dw_ch_zx_superset_activate_adid_d_incr_${partition_pt}
if [ ! -s $filename ];then
    echo "$filename size is 0 then exit!"
    exit 0
fi

17.Shell命令的输出信息同时显示在屏幕和保存到日志文件中

#直接覆盖日志文件   
ls -l | tee ./t.log   
#将输出内容附加到日志文件   
ls -l | tee -a ./t.log

18.sed替换指定字符开头的行

var="version=6.1.1"
sed -i '/^version=/c'$var'' /etc/config.txt
sed -i '/^command=/echo skip' /etc/config.txt
var="command=echo skip"
sed -i '/^command=/c'$var'' load_ods_ch_*
sed -i '/^command=/c'$var'' load_dw_ch_*
# grep
sed '/^[\t]/p' a.txt
grep $'\t' a.txt

19.sed中使用变量

line=ods_ch.ods_zx_cm_sessionclose_d_incr
sed -i "/${line}/d" test.done

20.变量为空则赋默认值

param1=ck2
host=${param1:-ck1}
echo $host

21.去掉注释和空的行

sed '/^#.*\|^$/d' 1.tt说明:^#.*说明以#字符开头的行,^$表示手空行,中间的\|是转义,表示或。d表示删除。

22.后台运行shell命令

nohup xxx.sh > /dev/null 2>&1 &

23.找出文件中不包含指定字符

grep -v "2020-04-09" old_hdfs_size.rst > 01.rst

24.sed -e一次更改多替换文本中多个值

sed -e 's/11/22/' -e 's/55/99/' num.txt # 这个命令将num.txt中的11替换成22, 55替换成99.

25.sed删除包含指定字符串的所有行

sed -e '/2019-12-0[12]/d' temp.txt > not_exist_in_new_hdp_cluster.txt

26.在每个以for开头的前面插入字符串

sed '/^for/i\kinit -kt /home/im_stats/im_stats.keytab im_stats@MICHAT.COM\n\n' load_dw_ch_dim_zx_user_register_path.sh
find . -name "*.sh" | xargs grep -il "hive" | xargs sed -i '/^for/i\kinit -kt /home/im_stats/im_stats.keytab im_stats@MICHAT.COM\n\n'
find . -name "*.sh" | xargs grep -il "stats11.im.int" | xargs sed -i 's/stats1[1-2].im.int/sjpt-hds-michat-35.sin01/g'
sed 's/stats1[1-2].im.int/sjpt-hds-michat-35.sin01/g' load_dw_ch_zx_ympns_push_cnt_d_incr.sh

27.正则表达式 \w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词:

 echo this is a test line | sed 's/\w\+/[&]/g'
 [this] [is] [a] [test] [line] 

28.awk找出top hdfs文件大小

hadoop fs -ls awk 'BEGIN{sum=0}{sum+=$5}END{print sum/1024/1024/1024 GB}'
awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' test.log
hadoop fs -ls /server_log/*/*/*2019*06* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-06".txt
hadoop fs -ls /server_log/*/*/*2019*07* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-07".txt
hadoop fs -ls /server_log/*/*/*2019*08* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-08".txt
hadoop fs -ls /server_log/*/*/*2019*09* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-09".txt
hadoop fs -ls /server_log/*/*/*2019*10* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-10".txt
hadoop fs -ls /server_log/*/*/*2019*11* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-11".txt
hadoop fs -ls /server_log/*/*/*2019*12* | awk 'BEGIN{size=0}{size+=$5}END{printf("%10.3f GB\t%10.3f GB\t\n",size/1024/1024/1024,size*3/1024/1024/1024)}' > "2019-12".txt

im_stats@datanode03:/data/pub-four-mfs/stats/tools/ods_handler$ cat 2019*.txt
  8144.689 GB    24434.067 GB
  8483.775 GB    25451.324 GB
  9414.310 GB    28242.930 GB
  8868.708 GB    26606.125 GB
  9782.030 GB    29346.090 GB
 10533.918 GB    31601.755 GB
 10857.728 GB    32573.185 GB

cat 2019*.txt | awk 'BEGIN{size=0;actsize=0}{size+=$1;actsize+=$3}END{printf("%10.3f GB\t%10.3f GB\n",size, actsize) }'

hadoop fs -ls /server_log/*/*/*2019-06* | less
-rw-r--r--   3 im_stats supergroup      70409 2019-06-05 14:33 /server_log/admin-web/pro-a-bonus-task03/admin-web.log.2019-06-04.gz

29.awk把第一列第二列的值加起来

awk 'BEGIN{sum=0;act=0}{sum+=$1;act+=$2}END{print sum,act}' test.log

im_stats@datanode03:/data/pub-four-mfs/stats/tools/ods_handler$ cat test.log
12 24 aa.log
6  12 bb.log
3  6  cc.log
im_stats@datanode03:/data/pub-four-mfs/stats/tools/ods_handler$ awk 'BEGIN{sum=0;act=0}{sum+=$1;act+=$2}END{print sum,act}' test.log
21 42

30.获取某个月的第一个星期日

halo_stats@abp-ops-imdcnginx-1:~$ year=`date +%Y`
halo_stats@abp-ops-imdcnginx-1:~$ month=`date +%m`
halo_stats@abp-ops-imdcnginx-1:~$ day=`date +%d`
halo_stats@abp-ops-imdcnginx-1:~$ echo $year $month $day
2019 11 27

halo_stats@abp-ops-imdcnginx-1:~$ ncal $month $year
    November 2019     
Su     3 10 17 24   
Mo     4 11 18 25   
Tu     5 12 19 26   
We     6 13 20 27   
Th     7 14 21 28   
Fr  1  8 15 22 29   
Sa  2  9 16 23 30 
# 以下2种都可以
ncal $month $year | grep -i "Su" | awk '{print $2}'
ncal $month $year | awk '{print $2}' | grep -v $year | head -1

31.大小写转换

1, 用tr
 
    例如:UPPERCASE=$(echo $VARIABLE | tr '[a-z]' '[A-Z]')   (把VARIABLE的小写转换成大写)
         LOWERCASE=$(echo $VARIABLE | tr '[A-Z]' '[a-z]')   (把VARIABLE的大写转换成小写)
 
2, 用typeset
 
    typeset -u VARIABLE  (把VARIABLE的小写转换成大写)
    typeset -l  VARIABLE  (把VARIABLE的大写转换成小写)
 
    例如:typeset -u VARIABLE
            VARIABLE="True"
            echo $VARIABLE
            输出为TRUE

32.查看某天所有hive表的大小

hadoop fs -ls /user/hive/warehouse/dw_flume.db/*/pt=2019.08.11.* | grep -v "_SUCCESS" | awk -F' ' '{print $5,$8}'   > 20190811_size.log

33.数组遍历

# 列表List
modes=(
"wifi_subset_users_base" # 一定要第一个运行
"adwords_first_new" # adwords纯新增用户
"adwords_old_first_new" # adwords历史所有纯新增用户
"googleplay_organic_first_new" # GP纯自然新增用户
"adwords_adjust_new" # adwords调整后新增用户
"adwords_old_adjust_new" # adwords历史所有调整后新增用户
"googleplay_organic_adjust_new" # GP调整后自然新增用户
"googleplay_old_organic" # 最后运行,有依赖前面的用户组
"googleplay_old_adjust_organic" # 最后运行,有依赖前面的用户组
)

for mode in "${modes[@]}";do
  echo "foo"
done

34.判断字符串是否包含某个字符

str="this is a string"
[[ $str =~ "this" ]] && echo "$str contains this" 
[[ $str =~ "that" ]] || echo "$str does NOT contain that"
结果为:
this is a string contains this
this is a string does NOT contains that
[[" 判断命令和 "=~"正则式匹配符号

35.全路径中获取脚本名

/root/xieyin/l1.sh
${line##*\/} # l1.sh
line=${line##*\/} # l1.sh
${line%%.*} #l1

var=http://www.aaa.com/123.htm.
1. # 号截取,删除左边字符,保留右边字符。
echo ${var#*//}
其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
即删除 http://
结果是 :www.aaa.com/123.htm

2. ## 号截取,删除左边字符,保留右边字符。
echo ${var##*/}
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符
即删除 http://www.aaa.com/

结果是 123.htm

3. %号截取,删除右边字符,保留左边字符
echo ${var%/*}   # %/* 表示从右边开始,删除第一个 / 号及右边的字符
结果是:http://www.aaa.com

4. %% 号截取,删除右边字符,保留左边字符
echo ${var%%/*}  # %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:

5. 从左边第几个字符开始,及字符的个数
echo ${var:0:5}  # 其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:

6. 从左边第几个字符开始,一直到结束
echo ${var:7}    # 其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm

36. awk截取")"右边的字符串

echo "sk2sl(kfei2p%fj4rsd)jasAdliels"|awk -F "\(|\)" '{print $2}'

37.在一些xml文件中,经常使用双引号,如果想要拿到双引号中的值,有两个小方法:

for example:

     <config case="SetasWallpaper_4" loop="3" path="Reliability/Key_Usage_MTBF/Picture_Stress/case"/>
        <config case="BrowserLaunchExit_1" loop="3" path="Reliability/Key_Usage_MTBF/Browser_Stress/case"/>
        <config case="VideoThumbnail_6" loop="3" path="Reliability/Key_Usage_MTBF/Video_Stress/case" />

这两个命令可以将上面双引号中的内容全部拿出来。

awk -F'"' '{i = 1; while (i <= NF) {if ($i ~/=$/) print $(i+1);i++}}' plan.xml

sed 's/[^"]*="[″]∗["]∗"[^"]*/\1/g;s/"/\n/g' plan.xml


简单一点可以使用下面的命令:只拿其中的一个值。

awk:awk -F "[\"\"]" '{print $2}' aaa.txt

sed:    cat aaa.txt | sed 's/.*".∗.∗".*/\1/'


echo "\`flag\` string," | awk -F "[\`\`]" '{print $2}'    
echo 'case="VideoThumbnail_6" loop="3" path' | awk -F "[\"\"]" '{print $2}'

38.nohup后台运行

nohup hive_get_partitions.sh tables.lst tab_partitions.txt result.csv > nohup.out 2>&1 &

39.单引号中使用单引号

echo ''"'"'${hiveconf:runDt}'"'"''

40.例如查找2013-08-082013-09-01号之间的文件,使用如下命令即可:

find /log/ -name 'production.log-2013*' -newermt '2018-08-01' ! -newermt '2019-09-01'


2011/09/08 12:00 时间开始找一天內的,会列出 2011/09/07 12:00 ~ 2011/09/08 12:00 时间內的文件
找出 3 天”以前”被改动过的文件 (前第三天以前 → 2011/09/05 12:00 以前的文件) (> 72 小时)


find /log/ -name 'production.log-2013*' -newermt '2018-08-01' ! -newermt '2019-09-01


find默认查找当前目录和子目录,通过maxdepth限制只查当前目录:
find . -maxdepth 1 -type f -name "*.php"

找当前目录下指定时间日期并删除
find . -maxdepth 1 -type f -newermt '2018-08-01' ! -newermt '2019-09-10' | xargs rm

41.获取hive表分区的简单方法

table="ods_im.wifi_nearby_pull3_d_incr"
pt_cols=(`hive -e "desc $table" | sed -n '1,/^# col_name/!p' | awk '{print $1}'`)
${pt_cols[0]}=pt
${pt_cols[1]}=hour
${pt_cols[2]}=t_source
                                 
/app/hadoop/hive/bin/hive -e "desc $table_name" 2>/dev/null                 
uid                     string                                      
longitude               string                                      
latitude                string                                      
sex                     string                                      
gender                  string                                      
listsize                string                                      
nextindex               string                                      
continueflag            string                                      
versioncode             string                                      
platform                string                                      
manufacturer            string                                      
osversion               string                                      
resultcode              string                                      
request_time            string                                      
clientip                string                                      
startindex              string                                      
fromtype                string                                      
is_useful               string                                      
app_id                  string                                      
channelid               string                                      
clienttype              string                                      
devicename              string                                      
ssid                    string                                      
bssid                   string                                      
uids                    string                                      
dim6                    string                                      
dim7                    string                                      
dim8                    string                                      
dim9                    string                                      
dim10                   string                                      
dim11                   string                                      
dim12                   string                                      
dim13                   string                                      
dim14                   string                                      
pt                      string                                      
hour                    string                                      
t_source                string                                      
                 
# Partition Information          
# col_name              data_type               comment             
                 
pt                      string                                      
hour                    string                                      
t_source                string 

42.将每行的最后一个,逗号改为分号)

# MAC
sed -E 's/\,([^\]*)$/\)\1/' $output
# Linux
# sed -r 's/\,([^\]*)$/ \1/' $output
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容