shell 实练(2)-du/awk/stat/行读取

来源:互联网 发布:淘宝p图用什么软件好 编辑:程序博客网 时间:2024/06/06 03:12

1、编写个shell脚本将当前目录下大于300bytes的文件复制到/test目录下

分两步:首先判断文件大小,再拷贝文件到指定目录

 #!/bin/bash
  2
  3
  4 du -ab . > du.txt         读取文件大小
  5 awk '$1 > 300{print $2}' du.txt > du2.txt          判断文件大小,成立则将文件名写入新文件中
  6 for line in `cat du2.txt`
  7 do
  8         test -e $line && cp $line ./test                     文件为档案则拷贝到指定目录
  9 done
 10

输出:

Loong:/home/yee/shell# mkdir test
Loong:/home/yee/shell# ll
总计 112
-rw-r--r-- 1 root root  147 11-01 14:32 ]
-rw-r--r-- 1 root root  300 11-01 09:17 abc.txt
-rw-r--r-- 1 root root  116 10-23 15:19 backup_date.sh
-rw-r--r-- 1 root root  463 10-30 10:31 calculate_birthday2.sh
-rwxrwxrwx 1 root root  910 10-29 16:21 calculate_birthday.sh
-rw-r--r-- 1 root root  506 10-24 17:05 calculate_time.sh
-rw-r--r-- 1 root root  386 10-25 14:24 case_practise.sh
--wx-wxrwx 1 root root  288 10-24 14:55 condition_judge.sh
-rw-r--r-- 1 root root   14 10-30 17:16 deal_passwd.sh
-rw-r--r-- 1 root root  425 11-01 15:18 du2.txt
-rw-r--r-- 1 root root 1305 11-01 15:20 du.txt
-rw-r--r-- 1 root root  503 10-23 11:23 full-name-output.sh
--wx-wxr-x 1 root root  255 10-24 11:32 judge_bracket.sh
-rw-r--r-- 1 root root  562 10-19 11:30 kkk.txt
-rw-r--r-- 1 root root  820 10-31 15:20 last.txt
-rw-r--r-- 1 root root  575 10-19 10:56 lll.txt
-rw-r--r-- 1 root root  193 10-23 16:20 multi.sh
-rw-r--r-- 1 root root 1386 10-30 15:44 passwd
-rw-r--r-- 1 root root  144 11-01 15:20 practise1.sh
-rw-r--r-- 1 root root    0 11-01 14:20 qq
-rw-r--r-- 1 root root  181 10-26 11:05 self_add2.sh
-rw-r--r-- 1 root root  181 10-29 17:11 self_add_practise.sh
-rw-r--r-- 1 root root  182 10-25 17:23 self_add.sh
-rw-r--r-- 1 root root  302 10-26 14:17 sum.sh
drwxr-xr-x 2 root root 4096 11-01 15:22 test
-rw-r--r-- 1 root root  957 10-30 15:20 test_practise.sh
-rw-r--r-- 1 root root  484 10-24 10:01 test_test.sh
--wx--x--x 1 root root  817 10-30 17:22 xaa
-rw-r--r-- 1 root root  569 10-30 17:22 xab
Loong:/home/yee/shell# sh practise1.sh
cp: 略过目录 “./test”                                                     不知道此处为何没有被test -e 给过滤掉,也可以先test -e 文件 && du -ab . > du.txt,过滤掉目录,但会增加步骤
cp: 略过目录 “.”
Loong:/home/yee/shell# cd test
Loong:/home/yee/shell/test# ll
总计 60
-rw-r--r-- 1 root root  463 11-01 15:23 calculate_birthday2.sh
-rwxr-xr-x 1 root root  910 11-01 15:23 calculate_birthday.sh
-rw-r--r-- 1 root root  506 11-01 15:23 calculate_time.sh
-rw-r--r-- 1 root root  386 11-01 15:23 case_practise.sh
-rw-r--r-- 1 root root  287 11-01 15:23 du2.txt
-rw-r--r-- 1 root root  503 11-01 15:23 full-name-output.sh
-rw-r--r-- 1 root root  562 11-01 15:23 kkk.txt
-rw-r--r-- 1 root root  820 11-01 15:23 last.txt
-rw-r--r-- 1 root root  575 11-01 15:23 lll.txt
-rw-r--r-- 1 root root 1386 11-01 15:23 passwd
-rw-r--r-- 1 root root  302 11-01 15:23 sum.sh
-rw-r--r-- 1 root root  957 11-01 15:23 test_practise.sh
-rw-r--r-- 1 root root  484 11-01 15:23 test_test.sh
--wx--x--x 1 root root  817 11-01 15:23 xaa
-rw-r--r-- 1 root root  569 11-01 15:23 xab
Loong:/home/yee/shell/test#

网络答案:

编写个shell脚本将当前目录下大于10K的文件转移到/tmp目录下

#/bin/sh

#Programm :

# Using for move currently directory to /tmp

for FileName in `ls -l | awk '$5>10240 {print $9}'`

do

mv $FileName /tmp

done

ls -al /tmp

echo "Done! "


判断文件大小:du,stat

du

du命令功能说明:统计目录(或文件)所占磁盘空间的大小。
语  法:du [-abcDhHklmsSx] [-L <符号连接>][-X <文件>][--block-size][--exclude=<目录或文件>] [--max-depth=<目录层数>][--help][--version][目录或文件]
常用参数:
-a或-all  为每个指定文件显示磁盘使用情况,或者为目录中每个文件显示各自磁盘使用情况。
-b或-bytes 显示目录或文件大小时,以byte为单位。
-c或–total 除了显示目录或文件的大小外,同时也显示所有目录或文件的总和。
-D或–dereference-args 显示指定符号连接的源文件大小。
-h或–human-readable 以K,M,G为单位,提高信息的可读性。
-H或–si 与-h参数相同,但是K,M,G是以1000为换算单位,而不是以1024为换算单位。
-k或–kilobytes 以1024 bytes为单位。
-l或–count-links 重复计算硬件连接的文件。
-L<符号连接>或–dereference<符号连接> 显示选项中所指定符号连接的源文件大小。
-m或–megabytes 以1MB为单位。
-s或–summarize 仅显示总计,即当前目录的大小。
-S或–separate-dirs 显示每个目录的大小时,并不含其子目录的大小。
-x或–one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
-X<文件>或–exclude-from=<文件> 在<文件>指定目录或文件。
–exclude=<目录或文件> 略过指定的目录或文件。
–max-depth=<目录层数> 超过指定层数的目录后,予以忽略。
–help 显示帮助。
–version 显示版本信息。
linux中的du命令使用示例:
1> 要显示一个目录树及其每个子树的磁盘使用情况
du /home/linux
这在/home/linux目录及其每个子目录中显示了磁盘块数。
2> 要通过以1024字节为单位显示一个目录树及其每个子树的磁盘使用情况
du -k /home/linux
这在/home/linux目录及其每个子目录中显示了 1024 字节磁盘块数。
3> 以MB为单位显示一个目录树及其每个子树的磁盘使用情况
du -m /home/linux
这在/home/linux目录及其每个子目录中显示了 MB 磁盘块数。
4> 以GB为单位显示一个目录树及其每个子树的磁盘使用情况
du -g /home/linux
这在/home/linux目录及其每个子目录中显示了 GB 磁盘块数。
5>查看当前目录下所有目录以及子目录的大小:
du -h .
“.”代表当前目录下。也可以换成一个明确的路径
-h表示用K、M、G的人性化形式显示
6>查看当前目录下user目录的大小,并不想看其他目录以及其子目录:
du -sh user
-s表示总结的意思,即只列出一个总结的值
du -h –max-depth=0 user
–max-depth=n表示只深入到第n层目录,此处设置为0,即表示不深入到子目录。
7>列出user目录及其子目录下所有目录和文件的大小:
du -ah user
-a表示包括目录和文件
8>列出当前目录中的目录名不包括xyz字符串的目录的大小:
du -h –exclude=’*xyz*’
9>想在一个屏幕下列出更多的关于user目录及子目录大小的信息:
du -0h user
-0(杠零)表示每列出一个目录的信息,不换行,而是直接输出下一个目录的信息。
10>只显示一个目录树的全部磁盘使用情况

应用举例:

Loong:/home/yee/shell# du -ah
4.0K    ./test_practise.sh
4.0K    ./lll.txt
4.0K    ./full-name-output.sh
4.0K    ./passwd

stat

STAT(1)                                 User Commands                                STAT(1)

NAME
       stat - display file or file system status                                       显示文件或文件系统状态

SYNOPSIS
       stat [OPTION] FILE...

DESCRIPTION
       Display file or file system status.

       -L, --dereference
              follow links

       -f, --file-system
              display file system status instead of file status

       -c  --format=FORMAT
              use  the  specified FORMAT instead of the default; output a newline after each
              use of FORMAT

       --printf=FORMAT
              like --format, but interpret backslash escapes, and do not output a  mandatory
              trailing newline.  If you want a newline, include \n in FORMAT.

       -t, --terse
              print the information in terse form

       --help display this help and exit

     --version
              output version information and exit

       The valid format sequences for files (without --file-system):

       %a     Access rights in octal

       %A     Access rights in human readable form

       %b     Number of blocks allocated (see %B)

       %B     The size in bytes of each block reported by %b

       %C     SELinux security context string

       %d     Device number in decimal

       %D     Device number in hex

       %f     Raw mode in hex

       %F     File type

       %g     Group ID of owner

       %G     Group name of owner

       %h     Number of hard links

       %i     Inode number

       %n     File name

       %N     Quoted file name with dereference if symbolic link

       %o     I/O block size

       %s     Total size, in bytes

       %t     Major device type in hex

       %T     Minor device type in hex

       %u     User ID of owner

       %U     User name of owner

       %x     Time of last access

       %X     Time of last access as seconds since Epoch

       %y     Time of last modification

%z     Time of last change

       %Z     Time of last change as seconds since Epoch

       Valid format sequences for file systems:

       %a     Free blocks available to non-superuser

       %b     Total data blocks in file system

       %c     Total file nodes in file system

       %d     Free file nodes in file system

       %f     Free blocks in file system

       %C     SELinux security context string

       %i     File System ID in hex

       %l     Maximum length of filenames

       %n     File name

       %s     Block size (for faster transfers)

       %S     Fundamental block size (for block counts)

       %t     Type in hex

       %T     Type in human readable form

       NOTE:  your shell may have its own version of stat, which usually supersedes the ver-
       sion described here.  Please refer to your shell's documentation  for  details  about
       the options it supports.


应用举例:
Loong:/home/yee/shell# stat practise1.sh
  File: “practise1.sh”
  Size: 144           Blocks: 8          IO Block: 4096   普通文件
Device: 806h/2054d    Inode: 3776576     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2012-11-01 15:23:00.000000000 +0800
Modify: 2012-11-01 15:20:55.000000000 +0800
Change: 2012-11-01 15:20:55.000000000 +0800

可以详细列出文件的大小,块及节点,建立修改时间等

Loong:/home/yee/shell# stat test
  File: “test”
  Size: 4096          Blocks: 8          IO Block: 4096   目录
Device: 806h/2054d    Inode: 3776522     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2012-11-01 15:45:46.000000000 +0800
Modify: 2012-11-01 15:23:00.000000000 +0800
Change: 2012-11-01 15:23:00.000000000 +0800

目录也适用。

2、编写shell脚本获取本机的网络地址

方法一:

#!/bin/bash
  2
  3 ifconfig |awk '/addr:/{print }' >1.txt
  4  awk 'BEGIN{FS="inet addr:"}{print "the IP is " $2}' 1.txt
  5  rm -f 1.txt

Loong:/home/yee/shell# sh practise1.sh
the IP is 172.16.3.62  Bcast:172.16.255.255  Mask:255.255.0.0
the IP is 127.0.0.1  Mask:255.0.0.0
Loong:/home/yee/shell#
合并为一句:ifconfig |awk '/addr:/{print }'|awk 'BEGIN{FS="inet addr:"}{print "the IP is " $2}'

方法二:

利用head,tail进行截取内容

                         ifconfig -a | head -n 2 | tail -n 1 | awk '{print$2}' | awk -F':' '{print$2}'`                      根据“:” 截取

Loong:/home/yee/shell# ifconfig -a | head -n 2 | tail -n 1 | awk '{print$2}' | awk -F':' '{print$2}'
172.16.3.62
Loong:/home/yee/shell# ifconfig -a | head -n 2 | tail -n 1 | awk '{print$2}'                              取第二栏
addr:172.16.3.62
Loong:/home/yee/shell# ifconfig -a | head -n 2 | tail -n 1
          inet addr:172.16.3.62  Bcast:172.16.255.255  Mask:255.255.0.0                  取后一行
Loong:/home/yee/shell# ifconfig -a | head -n 2                                                            取前两行
eth0      Link encap:Ethernet  HWaddr 00:23:9e:3c:4a:84  
          inet addr:172.16.3.62  Bcast:172.16.255.255  Mask:255.255.0.0
Loong:/home/yee/shell#

方法三:网络答案

方法一:从配置文件获取

#!/bin/bash

#This script print ip and network

file="/etc/sysconfig/network-scripts/ifcfg-eth0"

if [ -f $file ] ;then

IP=`grep "IPADDR" $file|awk -F"="'{ print $2 }'`

MASK=`grep "NETMASK" $file|awk -F"="'{ print $2 }'`

echo "$IP/$MASK"

exit 1

fi

 

 方法二:(实际执行并不正确)

#!/bin/bash

#This programm will printf ip/network

#

IP=`ifconfig eth0 |grep 'inet ' |sed's/^.*addr://g'|sed 's/ Bcast.*$//g'`

NETMASK=`ifconfig eth0 |grep 'inet '|sed's/^.*Mask://g'`

echo "$IP/$NETMASK"

exit

Loong:/home/yee/shell# sh practise1.sh
practise1.sh: 7: seds/^.*addr://g: not found
practise1.sh: 9: seds/^.*Mask://g: not found
/
Loong:/home/yee/shell#

3、Shell编程,判断一文件是不是字符设备文件,如果是将其拷贝到 /dev目录下。

首先得明白什么是字符设备文件?如何判别一个文件是否是字符文件?知道了判别标准后,再进行一一读取并进行拷贝。

先说字符设备文件,通过ls -l 就可判别

我们平时用ls -l 命令查看一个目录下的文件和子目录的详悉信息时,会得到一个详细的文件和目录名列表.这个列表包含了文件的属性,所属用户,所属组,创建时间,文件大小等等信息;讲解一下用ls -l命令得到的文件列表每一个字段的意思

[root@gucuiwen root]# ll
总用量 4055
-rw-r--r-- 1 root root 1581 11月 24 18:14 anaconda-ks.cfg
drwxr-xr-x 2 root root 208 12月 1 13:50 babylinux
lrwxrwxrwx 1 root root 9 1月 4 11:06 disk1.link.png -> disk1.png
-rwxr-xr-x 1 root root 13695 11月 30 16:51 fangkuai.sh
drwxr-xr-x 2 root root 208 12月 28 12:06 FreeBSD
-rw-r--r-- 1 root root 2315 11月 25 17:19 getMBR.png
brw-r----- 1 root root 3, 1 1月 4 11:06 hda1
drwxr-xr-x 2 root root 296 12月 31 11:53 htmls
-rw-r--r-- 1 root root 21369 11月 24 18:12 install.log
-rw-r--r-- 1 root root 0 12月 18 10:44 tset
crw-r----- 1 root root 4, 65 1月 4 11:08 ttyS1
-rw-r--r-- 1 root root 9754 12月 1 11:25 X.sxw
-rw-r--r-- 1 root root 8704 11月 29 12:22 员工信息.xls

可以看到,用ls -l命令查看某一个目录会得到一个9个字段的列表.

#######################
第1行:总用量(total)
#######################
这个数值是该目录下所有文件及目录列表第5个字段的和(以k为单位),也就是该目录的大小.请注意和该目录下的文件和子目录下文件的总合做区分.这个数字和du /root 得到的数字的大小是不一样的.可以用awk命令来验证.

用awk累加第5字段得到的数值:

[root@gucuiwen root]# ls -l |awk 'BEGIN{sum=0}{sum+=$5}END{print sum}'
4104092

转化成以K为单位:

[root@gucuiwen root]# ls -l |awk 'BEGIN{sum=0}{sum+=$5}END{print sum/1024}'
4007.9

用ls -l得到的数值:
总用量 4055

用du -sh /root得到的数值:
[root@gucuiwen root]# du -sh /root
127M /root

可以看到累加第5个字段得到的值和total显示的是一样的(因为具体算法的不同,略微有差别).得到的数值实际上是root目录的大小(把root目录看成是一个特殊的文件,就可以理解什么是目录的大小).而用du得到的数值是root目录下所由文件和子目录下全部文件的大小的总合.


########################
第1字段:
文件属性字段
########################

文件属性字段总共有10个字母组成,第一个字母表示文件类型,如果这个字母是一个减号"-",则说明该文件是一个普通文件.字母"d"表示该文件是一个目录,字母"d",是dirtectory(目录)的缩写.请注意,一个目录或者说一个文件夹是一个特殊文件,这个特殊文件存放的是其他文件和文件夹的相关信息.

如果该字母是"l",表示该文件是一个符号链接.符号链接的概念类似于windows里的快捷方式.字母"l"是link(链接)的缩写.在UNIX类系统中,一个文件可以有多个文件名,一个文件的多个文件名之间互称为硬链接(hard link).这些文件头可以指向同一个文件,删除其中一个文件名并不能删除该文件,只有把指向该文件的所有硬链接都删除,这个文件所占用的空间才真正被释放,该文件才真正被删除.这和windows是有很大区别的,windows中不允许一个文件有两个以上文件名,如果存在这中情况,则被认为是文件系统错误.如果你以前在windows下玩过DEBUG就知道,可以用DEBUG修改一张软盘上的根目录,使一个文件同时具有两个文件名.但是修改好后用 scandisk监测的时候会被认为是交叉链接错误.

开头为b的表示块设备文件(block),,设备文件是普通文件和程序访问硬件设备的入口,是很特殊的文件.它的没有文件大小,只有一个主设备号和一个辅设备号.上面的hda1就是一个设备文件,具有主设备号3和辅设备号1.表示第一个硬盘第一个分区.

另外,如果第一个字母为c表示该文件是一个字符设备文件(character),一次传输一个字节的设备被称为字符设备,比如键盘,字符终端等,传输数据的最小单位为一个字节.一次传输数据为一整块的被称为块设备,比如硬盘,光盘等.最小数据传输单位为一个数据块(通常一个数据块的大小是512字节).

好了,知道了什么是字符设备文件,也知道了就是看最前面的那个字母是不是c;那现在还有什么困难呢!@@

由于字符设备文件太少,所以选目录文件作为操作对象,便于观察

  1 #!/bin/bash
  2
  3
  4 ls -l |awk '$1 ~/d/ {print$0}'|awk '{print $NF}' > 1.txt     先找到“d”开头的目录文件,提取出该行,再提取出最后一列(不能按顺序取$7,实际排列并不整齐),输出到文件
  5 for line in `cat 1.txt`
  6 do      
  7         cp -r $line /dev
  8 done
  9 rm -f 1.txt
 10
Loong:/home/yee/shell# ll
总计 124

-rw-r--r-- 1 root root    0 11-01 14:20 qq
-rw-r--r-- 1 root root  181 10-26 11:05 self_add2.sh
-rw-r--r-- 1 root root  181 10-29 17:11 self_add_practise.sh
-rw-r--r-- 1 root root  182 10-25 17:23 self_add.sh
-rw-r--r-- 1 root root  302 10-26 14:17 sum.sh
drwxr-xr-x 2 root root 4096 11-01 15:23 test
drwxr-xr-x 2 root root 4096 11-02 14:08 test1
drwxr-xr-x 2 root root 4096 11-02 14:09 test2
drwxr-xr-x 2 root root 4096 11-02 14:09 test3
-rw-r--r-- 1 root root  957 10-30 15:20 test_practise.sh
-rw-r--r-- 1 root root  484 10-24 10:01 test_test.sh
--wx--x--x 1 root root  817 10-30 17:22 xaa
-rw-r--r-- 1 root root  569 10-30 17:22 xab
Loong:/home/yee/shell#
Loong:/home/yee/shell# sh -x practise1.sh
+ ls -l
+ awk $1 ~/d/ {print$0}
+ awk {print $NF}
+ cat 1.txt
+ cp -r test /dev
+ cp -r test1 /dev
+ cp -r test2 /dev
+ cp -r test3 /dev
+ rm -f 1.txt
Loong:/home/yee/shell#

参考程序:(看来对题意理解有偏差呀,是对输入的文件判断,更简单呀,不过要知道【】的参数-c)

#!/bin/sh

FILENAME=

echo “Input file name:”

read FILENAME

if [ -c "$FILENAME" ]

then

cp $FILENAME /dev

fi


另外附一些参考的知识点:

A、shell读取文件的每一行

写法一:

----------------------------------------------------------------------------

#!/bin/bash

 

while read line

do

    echo $line

done < filename(待读取的文件)

----------------------------------------------------------------------------

 

写法二:

----------------------------------------------------------------------------

#!/bin/bash

 

cat filename(待读取的文件) | while read line

do

    echo $line

done

----------------------------------------------------------------------------

 

写法三:

----------------------------------------------------------------------------

for line in `cat filename(待读取的文件)`

do

    echo $line

done

----------------------------------------------------------------------------

 

说明:

for逐行读和while逐行读是有区别的,如:

$ cat file

1111

2222

3333 4444 555

 

$ cat file | while read line; do echo $line; done

1111

2222

3333 4444 555

 

$ for line in $(<file); do echo $line; done

1111

2222

3333

4444

555

B、ls -l命令详解

http://hi.baidu.com/luyunwen/item/fedc5a1559f6a0f8ddeeca15







原创粉丝点击