ChinaUnix技术实践之四----Shell编程大赛!
问题1:
用最简洁的命令列出当前目录下的一级子目录,可以不包含隐藏目录(目录名以.开头的目录)
--答案:
1)tree -d -L 1
2)ls -d */
3)du --max-depth=1
4)find ./* -maxdepth 0 -type d
5)find * -type d -prune -print
6)find ! -path . -type d -prune -print
7)ls -F|grep "/"
问题2:
GNU sed 提供了-i选项,为什么有人说sed -i 并不象 ed 一样真正的编辑文件?(提示:观察文件改变前后的inode)
--答案:
区别在于交互式,因为sed只适用于非交互式的场合(可以认为这是一种弊端,因为会有临时文件产生)。
同时,使用sed -i编辑文件会导致文件的inode改变。
ed 是直接编辑文件,sed 是生成临时文件,然后改名实现的。
问题3:
用shell写一个cgi脚本,提供一个简单的webmail介面,将本地的一个文件通过web服务器发送到指定的邮箱
--答案:
#!/bin/bash
echo -e "Content-type: text/htmln"
if (( $# == 0 ));then
# main
cat <
收件人: 
标    题: 
正    文: 
附    件: 
EOF
else
if [[ ${QUERY_STRING} == "send" ]] && [[ ${REQUEST_METHOD} = POST ]];then
cd /tmp
cat - >/tmp/$.mf
typeset -x _F=$(awk '{if($0~/^Content-Disposition.+filename/)print gensub(".+filename="(.+)".*"," 1","g",$0)}' $.mf)
typeset -x State="${CONTENT_TYPE##*=}"
if [ ! -z ${_F} ];then
typeset -x $(awk 'BEGIN{FS="rn";RS=ENVIRON["State"]}{if($2~/Address/)print "rcptto=x22"$4"x22";
if($2~/Subject/)print "subject=x22"$4"x22"
if($2~/Info/)print "info=x22"$4"x22"
if($2~/filename/)printf("%s",$5)>ENVIRON["_F"]
}' $.mf)
echo "${info}"|mutt -a ${_F} -s "${subject}" ${rcptto}
else
echo "${info}"|mutt -s "${subject}" ${rcptto}
fi
rm -f $.mf ${_F}
fi
cat <
Redirect
EOF
fi
问题4:
awk -F'' 与 awk -F '' 一样吗?
--答案:
不一样,-F''的话awk无法解读-F变量。
awk -F '' 可以使用 NULL 为分隔符。
awk -F'' 不能使用 NULL 为分隔符。起引号内必须赋值.
问题5:
这条语句有什么作用?
sed -if /script/scr.sedcc test.txt
--答案:
sed调用文件/script/scr.sedcc执行,对test.txt直接处理
问题6:
#!/bin/sh
# the next line restarts using tclsh
exec tclsh "$0" "$@"
是如何执行的?与"#!/usr/local/bin/tclsh"相比,它有什么优点?
--答案:
1)执行过程:
第一种会导致sh和tclsh都去执行脚本,exec仅通过sh执行,sh先执行脚本,把第二行作为注释,
然后执行第三行,当执行到exec的时候停止sh的处理,转而启用tclsh,这个时候tclsh会重新将整个脚本再执行一次,
由于这个时候第二行末尾有个续行符,所以tclsh将所有三行都当成了注释。
2)优点
a)tclsh脚本可以位于任意位置(只要是在$PATH中,shell能找到的就行),
也就是说并不需要讲绝对路径写到脚本中去
b)它能够突破文件名为30个字符的限制
c)这种写法甚至在tclsh本身是shell脚本的时候也能执行
问题7:
#!/bin/sed -f" shebang 后可有其它字符吗?为什么?
--答案:
不能!!!(空格可以有)
对于Shebang lines(即#!打头的行),一般只允许在解释器后面跟一段空格,
这也就是为什么所有sed的参数不能分开的应用于Shebang line的原因
(比方说你不能想当然的写成#!/usr/bin/sed -E -f,因为这是不允许的)。
问题8:
GNU awk的$1=$1到底有什么作用?$0=$0呢?
--答案:
$1=$1 用当前的OFS重构 $0 NF 不改变
$0=$0 用当前的 FS重构 $1..$N NF 会改变
问题9:
写一个shell脚本,输出CU现有的版面和相应版主,并统计有多少个版面及多少个版主。
--答案:
#--------------------------
#!/bin/bash
:>moderator_num
main_url="http://bbs2.chinaunix.net"
wget -q "$main_url" -O index.html
Total_pages=`grep -o '^.*a>' index.html | wc -l`
sub_url=(`grep -o '^.*a>' index.html | grep -o 'forum-.*html' | tr 'n' ' '`)
sub_page=(`grep -o '^.*a>' index.html | awk -F'[<>]' '{print $3}' | tr 'n' ' '`)
for (( i=0; i moderator_list=(`wget -qO- $main_url/${sub_url[i]} | sed -rn '/^
#-------------------------------
#!/bin/bash
#
PATH=${PATH}:/sbin:/usr/sbin:/usr/local/bin
Url="http://bbs.chinaunix.net"
N=0
curl --connect-timeout 10 -m 60 --retry 5 -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" ${Url} -o /tmp/tempfile 2>/dev/null
awk '{if($0~"bold subject"){getline;getline;printf("%s %sn",gensub("href..(.+)"","|1","g",$2),gensub(">| /tmp/tempfile >/tmp/tempfile1
while read Url1 Name;do
let N++
printf "%-2s -- %-20s%-20sn" ${N} ${Name} "[${Url}/${Url1}]" >>/tmp/tempfile3
curl --connect-timeout 10 -m 60 --retry 5 -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" ${Url}/${Url1} -o /tmp/tempfile2 2>/dev/null
awk 'BEGIN{FS="[<>]"}{if($1=="版主: ")for(i=3;i>/tmp/tempfile3
doneawk '{printf("%-15s",($1=="版主:")?"["$2"] ":"nn"$0"n")}' /tmp/tempfile3
echo '#------------------------------------------------------------------#'
awk '{if($0~/^版主/){A[$0]++}else{B[$0++]}}END{printf("CU现有版面[%d]t版主[%d]个n",length(B),length(A))}' /tmp/tempfile3
rm -f /tmp/tempfile*
#----------------------------------
#!/bin/bash
# root url
RURL="http://bbs.chinaunix.net"
# 获取版块
# in: 如果无参数调用,获取首页的所有版块;
# 如果提供一个参数调用, 返回该版块内的子版块
# out: 输出获取到的版块名
function get_forums()
{
if [ -z $1 ]; then
curl $RURL -o- 2>/dev/null | grep -Eo 'forum[^"]+.html' | sort -u
else
curl $RURL/$1 -o- 2>/dev/null | grep -Eo 'forum[^"]+.html' |
grep -v "$1" | sort -u
fi
}
# 获取指定版块的版块名
# in: 版块, 如: forum-216-1.html
# out: 输出该版块的名字
function get_forum_name()
{
curl $RURL/$1 -o- 2>/dev/null | grep forumheader -A 1 |
iconv -f GBK -t UTF-8 |
cut -d'>' -f2 | cut -d '}
# 获取指定版块的所有版主
# in: 版块, 如: forum-216-1.html
# out: 输出该版块的所有版主
function get_moderators()
{
test -z $1 && echo "usage $0 curl $RURL/$1 -o- 2>/dev/null |
grep modedby -A 1 | iconv -f GBK -t UTF-8 |
tr ',' 'n' |
cut -d'>' -f2 | cut -d' grep -Ev '^
}
function main()
{
my_forums=$(get_forums)
for x in $my_forums; do
get_forum_name $x
echo -e "t$(get_moderators $x | xargs)"
my_sub_forums=$(get_forums $x)
for sub_x in $my_fub_forums; do
get_forum_name $sub_x
echo -e "t$(get_moderators $sub_x | xargs)"
done
done
}
TMPFILE=$(mktemp)
main | tee $TMPFILE
# 版块数
forum_num=$(grep -Ev '^[[:space:]]' $TMPFILE | grep -Ev '^ | wc -l)
echo "ChinaUnix共有$forum_num个版块"
# 版主数
moderator_num=$(grep -E '^[[:space:]]' $TMPFILE | tr -d 't' | tr ' ' 'n' | grep -Ev '^ | wc -l)
echo "ChinaUnix共有$moderator_num个版主"
rm -f $TMPFILE
问题10:
人机五子棋。原始规则(无禁手),最好加上标准规则,三手交换(即黑下第二手之后白可以提出交换),
五手两打,黑三三禁手,黑四四禁手,黑长连禁手(超过5个子相连),逢五无禁手。白无禁手,长连也算胜。
关键在于人机对下。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22661144/viewspace-1050083/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/22661144/viewspace-1050083/