Linux Daily2

573 查看

1. 文件编码

查看文件编码格式

# vi .vimrc
:set fileencoding
  fileencoding=utf8
set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1

# vi XXX.file
:set fencs?
  fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1
:set fenc?
  fileencoding=cp936
:set enc?
  encoding=utf-8

cat文件乱码

Windows下生成的纯文本文件,其中文编码为GBK,在Ubuntu下显示为乱码,可以使用iconv命令进行转换:

# iconv -f gbk -t utf8 source_file > target_file
iconv: 未知 5 处的非法输入序列

GBK转码实践

#!/bin/bash
if [ "$#" != "2" ]; then
  echo "Usage: `basename $0` dir filter"
  exit
fi
dir=$1
filter=$2
echo $1

for file in `find $dir -name "$2"`; do
  echo "$file"
  iconv -f gbk -t utf8 -o $file $file
done

执行方式: 第一个参数是目录, 第二个是文件选择

~/ftp/GBK2UTF-8_batch.sh ./  M_EP_PD_AQI*
~/ftp/GBK2UTF-8_batch.sh ./  M_EP_PH_AQI*
~/ftp/GBK2UTF-8_batch.sh ./  M_METE_CITY_PRED*
~/ftp/GBK2UTF-8_batch.sh ./  M_METE_WEATHER_LIVE*

执行最后一个, 文件>32kb, 报错:

4361 总线错误 (core dumped) iconv -c -f gbk -t utf8 -o $file $file

解决方式: http://myotragusbalearicus.wordpress.com/2010/03/10/batch-convert-file...
还是不行: http://www.path8.net/tn/archives/3448
使用//IGNORE, 成功!

  iconv -f gbk//IGNORE -t utf8//IGNORE $file -o $file.tmp

注意原始文件必须是和-f对应,如果原始文件是utf8, 要再次转换成utf8, 也会报错.

GBK2UTF8.sh

#!/bin/bash
if [ "$#" != "2" ]; then
  echo "Usage: `basename $0` dir filter"
  echo "sample: ./GBK2UTF8.sh /home/midd/ftp/fz12345/back/2015-03 fz12345_*.txt"
  exit
fi
dir=$1
filter=$2
tmp='T'
echo $1

for file in `find $dir -name "$2"`; do
  echo "$file"
  #iconv -f gbk -t utf8 -o $file $file
  #Notic, the Source File should not utf8 format. or u 'll get error
  iconv -f gbk//IGNORE -t utf8//IGNORE $file -o $tmp$file
done

磁盘

查看文件大小

ll -h只能查看文件的大小. 不能查看文件夹占用的大小.

查看某个目录总的大小

cd dir
du -h ./

在最后会列出这个文件夹占用的大小. 或者不用cd, 直接du -h dir

扩容操作

查看磁盘使用量: df -mh
根目录/达到了100% : /dev/mapper/vg_datanode01-LogVol00

查看卷: vgdisplan:

---Volume group ---
VG Name    vg_datanode01

--- Logical volume ---
LV Path      /dev/vg_datanode01/LogVol00

扩容:

lvextend -L +10G  /dev/mapper/vg_datanode01-LogVol00
resize2fs /dev/mapper/vg_datanode01-LogVol00

3. 系统

文件数和进程数

[midd@datanode01 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62700
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[midd@datanode01 ~]$ ps -ef | grep ETL
midd     14369     1  0 Mar29 ?        00:00:00 ETL_ScheduleCenter     
midd     14370 14369 99 Mar29 ?        5-06:14:46 ETL_ScheduleServer     
midd     14442 14369  6 Mar29 ?        02:33:41 ETL_ServerManger       
midd     41892 41839  0 10:19 pts/3    00:00:00 grep ETL

[midd@datanode01 ~]$ lsof -p 14369 | wc -l
20
[midd@datanode01 ~]$ lsof -p 14370 | wc -l
928
[midd@datanode01 ~]$ lsof -p 14442 | wc -l
4169
[midd@datanode01 ~]$ cat /proc/sys/fs/file-max
792049

[midd@datanode01 ~]$ su - 
[root@datanode01 ~]# vi /etc/security/limits.conf
* soft nofile 65536 * hard nofile 65536
添加以上, 其中*表示任何用户.  注意要用root用户执行. 

或者使用root用户添加指定用户的文件数和进程数:

echo '########################for ETL 4.1.0' >> /etc/security/limits.conf
echo 'midd soft nofile 65536' >> /etc/security/limits.conf
echo 'midd hard nofile 65536' >> /etc/security/limits.conf
echo 'midd soft nproc 131072' >> /etc/security/limits.conf
echo 'midd hard nproc 131072' >> /etc/security/limits.conf
echo 'midd soft nofile 65536' >> /etc/security/limits.conf
echo 'midd hard nofile 65536' >> /etc/security/limits.conf
echo 'midd soft nproc 131072' >> /etc/security/limits.conf
echo 'midd hard nproc 131072' >> /etc/security/limits.conf

然后使用midd用户验证ulimit

[midd@datanode01 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62700
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 131072
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

另外方法:http://gaozzsoft.iteye.com/blog/1824824

1.使用ps -ef |grep java   (java代表你程序,查看你程序进程) 查看你的进程ID,记录ID号,假设进程ID为122.使用:lsof -p 12 | wc -l    查看当前进程id为12的 文件操作状况    执行该命令出现文件使用情况为 10523.使用命令:ulimit -a   查看每个用户允许打开的最大文件数    发现系统默认的是open files (-n) 1024,问题就出现在这里。4.然后执行:ulimit -n 4096
     将open files (-n) 1024 设置成open files (-n) 4096
这样就增大了用户允许打开的最大文件数

内存/进程

free
free -m     以MB为单位
free -g     以GB为单位

df
df -m       以MB
df -h       以人类(human)可读的, 即GB

pstree -p | wc -l   

进程和端口

根据端口号查询进程名字

lsof -Pnl +M -i4[i6] | grep 20880

top命令

按M可以按照Memory排序, 按P按照CPU排序
按u可以选择指定的user, 只显示该用户的进程
top -p $(pidof mongod)      只显示指定的进程

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                      
 4735 midd      20   0 30.1g 748m 4944 S  2.0  9.5 102:39.94 mongod       

killall 命令可以杀死同一个进程的所有子进程.
如果用ps -ef | grep 则要一个一个杀.
比如ps -ef | grep ETL 显示一共由三个相关进程

[midd@datanode01 bin]$ ps -ef | grep ETL
midd      4812 41955  0 16:01 pts/3    00:00:00 grep ETL
midd     42276     1  0 15:52 ?        00:00:00 ETL_ScheduleCenter     
midd     42277 42276 99 15:52 ?        00:15:35 ETL_ScheduleServer     
midd     42345 42276  7 15:53 ?        00:00:34 ETL_ServerManger

而用killall 只需要一行: killall ScheduleCenter

用户和权限

添加用户, 设置密码

useradd -d /home/postgres postgres 
passwd postgres 

更改读写权限, 地柜目录使用大写的R. (注意scp时用的是小写的r)

chmod 755 file
chmod -R 755 folder

更改用户名:组

chown hadoop:hadoop -R folder

定时任务cron

1.编写脚本

# vi /usr/lib/zookeeper/bin/cron.day 
#bin/sh
cd /usr/lib/zookeeper/bin
./zkCleanup.sh /opt/hadoop/zookeeper/version-2 5
echo 'clean up end...'

2.更改脚本权限

# chmod 755 /usr/lib/zookeeper/bin/cron.day 

3.定时调度策略

# cd /etc/cron.d
# vi /etc/cron.d/zk.cron 
0 13 * * * root run-parts /usr/lib/zookeeper/bin/cron.day

4.导入调度配置

# crontab zk.cron

5.查看调度列表

# crontab -l
0 13 * * * root run-parts /usr/lib/zookeeper/bin/cron.day

6.查看是否调度的日志

# tail -f /var/log/cron
Apr  1 13:00:01 namenode02 CROND[41859]: (root) CMD (root run-parts /usr/lib/zookeeper/bin/cron.day)

其他知识点:

# vi /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

4. 文件操作

wordcount计数

计算文件的行数: wc -l file.txt
要统计单词数量, 加上w选项. L选项表示最长行的长度. 注意这是一整行.不能按照列计算最长长度.

帮助信息: $ wc --help. 如果不知道一个命令, 最好看看--help

用法:wc [选项]... [文件]...
 或:wc [选项]... --files0-from=F
  -c, --bytes            print the byte counts
  -m, --chars            print the character counts
  -l, --lines            print the newline counts
  -L, --max-line-length 显示最长行的长度
  -w, --words           显示单词计数
      --help        显示此帮助信息并退出
      --version     显示版本信息并退出

grep查找

ps -ef | grep ETL  查看进程
cat fz12345_original.txt | grep FZ15032700599 查找一个文件里的字符串

查找目录下的文件里的内容

cat foder/*.* | grep XXX
find /etc/ -name "*" | xargs grep XXX

注意: 第一个cat命令无法用于递归子目录, 第二个命令/etc后面必须跟上/, 而且name是*

大文件定位到某一行

sed -n '111,112p' file.txt

find文件名

在指定目录查找文件名: find ~/repo -name *tmp*

使用管道, xargs表示递归找到的每个值. 如果是文件, 使用rm. 如果是文件夹, 用rm -rf.
递归删除svn文件夹: find SVNFOLDER -name .svn | xargs rm -rf
递归删除文件: find ~/repo -name *tmp* | xargs rm

文件内容替换

\n替换为, :%s/\n/,/

ORACLE类型转换为hive类型:

%s/STRING(.*)/STRING/
%s/VARCHAR2(.*)/STRING/
%s/CHAR(.*)/STRING/
%s/DATE,/STRING,/
%s/date,/STRING,/
%s/INTEGER/INT/
%s/NUMBER(..)/BIGINT/
%s/NUMBER(.)/INT/
%s/NUMBER(.*)/DOUBLE/
%s/.not null//

rename批量修改文件名

rename .XLS .xlsx *.XLS     把文件名=.XLS的替换成.xlsx
rename \_linux '' *.txt         把文件名=_linux的替换成空, 注意_要用转义, 即去掉文件名包含_linux的
rename -Unlicensed- '' *.xlsx       

exp脚本

dacp_720.exp
#!/usr/bin/expect
set tableName [lindex $argv 0]
#spawn ssh dacp@172.17.212.72 /home/dacp/dp-executor/dacp-dp-executor-1.0.0.RELEASE/go.sh \
#20141218 lhx_fzdc_test01
spawn ssh dacp@172.17.212.72 \
/home/dacp/dp-executor/dacp-dp-executor-1.0.0.RELEASE/go.sh 20141218 $tableName
expect "password:"
send "dacp@123\n"
interact

http://wgkgood.blog.51cto.com/1192594/1271543
http://blog.51yip.com/linux/1462.html

自动交互

http://bbs.chinaunix.net/thread-915007-1-1.html
http://os.51cto.com/art/200912/167898.htm

ftp文件夹下载

wget ftp://172.17.227.236/ctos_analyze/data/tmp/* --ftp-user=ftpd --ftp-password=ftpd123 -r
*必须要有, 最后的-r表示目录下载

wget -r -l 1 http://www.baidu.com/dir/

文件续传: wget -c xxx.file

文件按行数分割

$ wc -l dispatch2012.csv 
231272 dispatch2012.csv

$ split -l 60000 dispatch2012.csv dispatch2012_new.csv 
$ ll
-rw-r--r-- 1 hadoop hadoop 27649615  9月 27  2014 dispatch2012.csv
-rw-rw-r-- 1 hadoop hadoop  7115577  4月 14 19:08 dispatch2012_new.csvaa
-rw-rw-r-- 1 hadoop hadoop  7188497  4月 14 19:08 dispatch2012_new.csvab
-rw-rw-r-- 1 hadoop hadoop  7208496  4月 14 19:08 dispatch2012_new.csvac
-rw-rw-r-- 1 hadoop hadoop  6137045  4月 14 19:08 dispatch2012_new.csvad
$ wc -l dispatch2012_new.csv*
   60000 dispatch2012_new.csvaa
   60000 dispatch2012_new.csvab
   60000 dispatch2012_new.csvac
   51272 dispatch2012_new.csvad
  231272 总用量

压缩和解压

.tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gunzip FileName.gz解压2:gzip -d FileName.gz压缩:gzip FileName
.tar.gz 和 .tgz解压:tar zxvf FileName.tar.gz压缩:tar zcvf FileName.tar.gz DirName———————————————.bz2解压1:bzip2 -d FileName.bz2解压2:bunzip2 FileName.bz2压缩: bzip2 -z FileName
.tar.bz2解压:tar jxvf FileName.tar.bz2压缩:tar jcvf FileName.tar.bz2 DirName———————————————.bz解压1:bzip2 -d FileName.bz解压2:bunzip2 FileName.bz压缩:未知
.tar.bz解压:tar jxvf FileName.tar.bz压缩:未知———————————————.Z解压:uncompress FileName.Z压缩:compress FileName.tar.Z
解压:tar Zxvf FileName.tar.Z压缩:tar Zcvf FileName.tar.Z DirName———————————————.zip解压:unzip FileName.zip压缩:zip FileName.zip DirName———————————————.rar解压:rar x FileName.rar压缩:rar a FileName.rar DirName———————————————.lha解压:lha -e FileName.lha压缩:lha -a FileName.lha FileName———————————————.rpm解包:rpm2cpio FileName.rpm | cpio -div———————————————.deb解包:ar p FileName.deb data.tar.gz | tar zxf -———————————————.tar .tgz .tar.gz .tar.Z .tar.bz .tar.bz2 .zip .cpio .rpm .deb .slp .arj .rar .ace .lha .lzh .lzx .lzs .arc .sda .sfx .lnx .zoo .cab .kar .cpt .pit .sit .sea解压:sEx x FileName.*压缩:sEx a FileName.* FileName

5. vi

显示行号: :set number
打开文件定位到最后一行: vi + file.txt
从指定行删除到最后一行

方法1: 
使用set number计算当前行和最后一行的差比如100
输入100dd

6. Awk/sed

列编辑

replace(replace(DISPATCHMEMO,chr(10),''),chr(9),'')

awk '{print "<" $0 "> "}' O_FZ12345_CALLINFO>O_FZ12345_CALLINFO2
awk '{print "select count(*) from " $0 " union all \n"}' cl>cl2

awk '{print "replace(replace(" $0 ",chr(10),''),chr(9),'')"}' O_FZ12345_CALLINFO>O_FZ12345_CALLINFO2

awk '{print "replace(replace(" $0 ",chr(10),''),chr(9),'')"}' c3>c4

%s/,)/,'')/

alter table owner to etl;
awk '{print "alter table " $0 " owner to etl;"}' test>test2

列的最大长度

下面2个语句执行的结果不同??
打印结果时,用双引号
awk '{if (length($NF)>maxlength) maxlength=length($NF)} END {print maxlength" "$1" "$2" "$NF}' fz12345_original.txt

找出最后一列的最大长度  
awk '{if (length($NF)>maxlength) maxlength=length($NF)} END {print maxlength }' fz12345_original.txt   

找出最大长度的那一条记录  
awk 'length($NF)==2016 {print $1" "$2" "$NF}' fz12345_original.txt  

最后一列为空  
awk '{$NF="" ;print $0}' fz12345_original.txt  | head  

截取最后一列:  
awk '{print substr($NF, 0, 900)}' fz12345_original.txt  

打印一整行:  
awk '{print $0}' fz12345_original.txt  

打印第一列和最后一列, 最后一列被截取, 以\t分割  
awk '{$NF=substr($NF, 0, 900) ;print $1"\t"$NF}' fz12345_original.txt  | head  

截取最后一列, 并打印整行. 但是分隔符变成空格. 如果原先内容有空格,则无法正确解析  
awk '{$NF=substr($NF, 0, 900) ;print $0}' fz12345_original.txt  | head  

截取最后一列, 打印整行, 分隔符为\t  
awk 'BEGIN {OFS="\t"}{$NF=substr($NF, 0, 900) ;print $0}' fz12345_original.txt | head  

行的字段数不一样. 是因为如果有些字段值为空: 如果是空值,则不会被计算为一列!  
awk '{print NF}' fz12345.txt | head  
awk '{print NF}' fz12345_original.txt | head  

输出字段分隔符:  
awk 'BEGIN {OFS="\t"}{$NF=substr($NF, 0, 900) ;print $0}' fz12345_original.txt > fz12345.txt  
输入字段分隔符,输出字段分隔符:  
awk 'BEGIN {FS="\t";OFS="\t"}{$NF=substr($NF, 0, 900) ;print $0}' fz12345_original.txt > fz12345.txt  
输入字段,输入行,输出字段,输出行分隔符:  
awk 'BEGIN {FS="\t";RS="\n";OFS="\t";ORS="\n";}{$NF=substr($NF, 0, 900) ;print $0}' fz12345_original.txt > fz12345.txt  

awk FS="\t" '{$NF=substr($NF, 0, 900) ;print $0}' OFS="\t" fz12345_original.txt > fz12345.txt  


<http://coolshell.cn/articles/9070.html>  
awk  -F:'{print $1,$3,$6}' OFS="\t" /etc/passwd  
/etc/passwd文件是以:为分隔符的. 取出第1,3,6列. 以\t分割!  

一列转多行

hadoop@hadoop:~$ echo 'A|B|C|aa,bb|DD' | awk -F\| 'BEGIN{OFS="|"}{split($4,a,",");for(i in a){$4=a[i];print $0}}'
A|B|C|aa|DD
A|B|C|bb|DD
hadoop@hadoop:~$ echo 'A|B|C|aa|DD' | awk -F\| 'BEGIN{OFS="|"}{split($4,a,",");for(i in a){$4=a[i];print $0}}'
A|B|C|aa|DD

awk 'BEGIN{FS="\t";OFS="\t"}{split($5,a,",");for(i in a){$5=a[i];print $0}}' \
fz12345_dispatch_2014.txt > fz12345_dispatch_2014_2.txt

转换前文件:
2251562 FZ15032600537   福州市信访局    2015-03-26 16:29:50     福州市城乡建设委员会,福州市交通运输委员会       0       1       10      2015-04-10 16:29:50

转换后文件:
2251562 FZ15032600537   福州市信访局    2015-03-26 16:29:50     福州市城乡建设委员会    0       1       10      2015-04-10 16:29:50
2251562 FZ15032600537   福州市信访局    2015-03-26 16:29:50     福州市交通运输委员会    0       1       10      2015-04-10 16:29:50

去掉文件中的所有双引号: sed -i 's/"//g' dispatch2012.csv

将^M删除

sed -i 's/"//g' dispatch2012.csv                        ×
tr -d '^M' < dispatch2012_2.csv                     ×

alias dos2unix="sed -i -e 's/'\"\$(printf '\015')\"'//g' "      √
dos2unix dispatch2012_2.csv                         
sed -i -e 's/'\"\$(printf '\015')\"'//g' dispatch2012_2.csv     报错: bash: 未预期的符号 `(' 附近有语法错误

删除第一行: sed -i '1d;$d' dispatch2012_2.csv

第五列因为乱码直接改为空字符串!
awk 'BEGIN {FS=",";RS="\n";OFS="\t";ORS="\n";}{$5="";print $0}' dispatch2012.csv > dispatch2012_2.csv

7.其他

制作程序启动脚本:

arg=$1
cmd=''

if [ $arg == 'idea' ]; then
  cmd='/home/hadoop/tool/idea-IU-139.225.3/bin/idea.sh'
fi

echo '应用程序启动命令:$cmd'
nohup $cmd &