好久没有写shell了,以前也只是看过shell的语法,但是很少使用,今天朋友让我帮忙写个小脚本,重温了以下之前的shell语法,现记录如下
脚本的功能如下:对指定输入文件,随机提取指定个数的行,要求这些行不能重复。
第一个问题,如何使用shell产生随机数?
摘自http://www.anyside.org/papers/shell_random_cn.htm
1、使用shell变量$RANDOM
echo $RANDOM
2、使用awk的随机函数
awk 'BEGIN{srand();print rand()}'
3、使用系统设备文件/dev/random 和 /dev/urandom
dd if=/dev/random | od -a |sed 's/[^ ]*//;s/ //g' | head -3
或
dd if=/dev/urandom | od -a |sed 's/[^ ]*//;s/ //g' | head -3
例,产生9个0-33之间的随机数,如下
dd if=/dev/urandom | od -a |sed 's/[^ ]*//;s/[^0-9][^0-9]*//g;/^ *$/d;s/^/([0-9]/)$/0/1/g' | cut -b 1-2 | awk '{if($1<=33)print}' | head -9 | sed 's/$/ /g;' | tr -d '/n' && echo
补充:
/dev/random 提供优质随机数。
/dev/urandom提供伪随机数。速度更快、安全性较差的随机数发生器。
-- Liu Yuan.
©2002-2007 AnySide .All rights reserved.
我使用的是最简单的方法,(方法1).
第二:产生的随机数,是随机整数,范围在0-32767,对于指定文件,行数是一定的,我产生的随机行数应该介于0-总行数之间。
这个问题好解决,其他语言中可以直接求模。shell也可以。
如下:
line=`expr $RANDOM % $totalLine`
注意:以上是反引号。
第三,查看文件总行数:
有以下几种方法,a=`cat filename | wc -l `
第一种:
# awk '{print NR}' a|tail -n1
55
第二种:
begincwcw兄的这个:
# awk 'END{print NR}' a
55
第三种:
# grep -n "" a|awk -F: '{print $1'}|tail -n1
55
第四种:
# sed -n '$=' a
55
第五种
# wc -l a|awk '{print $1}'
55
第四,如何删除行尾的换行符
line=` echo $line | tr -s "[/n]" `
第五,提取文件地N行的内容。
cat $filename | head -n $linenum | tail -n 1.
脚本文件如下。
1 #!/bin/sh
2 times=0;
3 TotalLine=`cat $1 |wc -l `
4 if [ -e lineRecord.txt ] ;then
5 rm -rf lineRecord.txt
6 fi
7 touch lineRecord.txt
8 ToltalLine=`expr $TotalLine + 1`
9 while [ "$times" -lt "$2" ]
10 do
11 line=`expr $RANDOM % $TotalLine `
12 if [ $line -ne 0 ]; then
13 exist=`cat lineRecord.txt |grep $line`
14 exist=`echo $exist | tr -s "[/n]"`
15 if [ -z "$exist" ] ; then
16 echo $line >> lineRecord.txt
17 cat $1 | head -n $line | tail -n 1
18 times=`expr $times + 1`
19 fi
20 fi
21 done
22 rm -rf lineRecord.txt