编写一个shell程序,将文件的.txt后缀名删除的程序

答案一:
#!/bin/bash
for i in `ls *.txt`
do
p=`echo $i|awk -F. '{print $1}'`
mv $i $p
done

答案二:find -type f -name '*.txt' -print0 | xargs --null rename '.txt' ''

awk 合并一个文件

我有这样的需求,需要把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下
cat 1.txt
1 aa
2 bb
3 ee
4 ss

cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de

合并后的结果为:

1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de

实现的命令为:
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}'  1.txt  2.txt

解释:NR表示读取的行数,FNR表示读取的当前行数
所以其实NR==FNR 就表示读取2.txt的时候。 同理NR>FNR表示读取1.txt的时候
数组a其实就相当于一个map

split 分割大文件指定输出文件名

split 用做分割文件,你可以按照大小分割,也可以按照行数分割。
比如:
split  -l  10000   filename   
这个是依据行数来分割的,每10000行为一个小文件

split  -b  1m  filename   
这是按照大小来分割的,每1m为一个小文件

默认情况下,如果我们不指定输出的文件名,会以这样的形式出现在当前目录下 :  xaa  xab .... xaz xba xbb ... xbz  
那么如何指定输出的文件名字呢?
只需要这样即可:
split  -l  10000  filename   outfilename   
这里的outfilename 就为你指定的输出文件名,不过分割后的文件名为   outfilenameaa   outfilenameab ...

用shell编程,写一个筛出10001--20000范围内的质数的程序,可以用FOR循环

质数是指:在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数

#!/bin/sh
for((i=10000;i<=12000;i++))
do
        for((k=2;k<=i;k++))
        do
                if [ $k -eq $i ]
                then
                        echo "$i su shu"
                        break

                fi
                if [ $(($i%k)) -eq 0 ]
                then break
                fi
        done
done

随机生成字符串

dd if=/dev/random count=16 bs=1| xxd -ps   //32位

dd if=/dev/random count=24 bs=1| xxd -ps   //48位

除百度、Google外其他蜘蛛IP封锁脚本

本帖隐藏的内容需要回复才可以浏览

awk 中使用外部shell变量

如:
A=44
echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’

说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。有多少个变量需要赋值,就需要多少个-v选项。与之等价的:

应用于脚本中:
#! /bin/bash

sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
        echo "[$id]"
        awk -v id2=$id -F ':' '$1==id2 {print $2}' filename  // 另外的方式为: awk -F ':' '$1=="'id2'" {print $2}' filename  
done

附件:
cat filename
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123

运行脚本后结果为:
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123

其他关于awk相关文章

linux shell下得到指定字符串的md5加密字符串

echo test |md5sum|awk '{print $1}'

结果是
d8e8fca2dc0f896fd7cb4cb0031ba249

用shell脚本判断某个日志5分钟有没有变更

#! /bin/bash
## 判断日志在5分钟内有没有更改
## Writen by Aming.

logfile="/var/log/messages"
l=`find $logfile -mmin -5|wc -l`
if [ "$l" -eq "0" ] ; then
        echo "日志5分钟内没有变更."
else
        echo "日志5分钟内有变更."
fi

封灌水机ip脚本

#! /bin/bash

## This script if for kill post robots.
## Writen by Li Shiming 2010-08-19.

while :; do
logf=/home/logs/client/access.log
tmplog=/tmp/tmplog.txt
ipf=/tmp/killpost.ip
badipf=/var/log/badip.log
conf=/etc/killpost.conf
n1=`grep 'n1=' $conf|awk -F'=' '{print $2}' `
n2=`grep 'n2=' $conf|awk -F'=' '{print $2}' `
n3=`grep 'n3=' $conf|awk -F'=' '{print $2}' `

/sbin/iptables -nvL |grep REJECT |grep tcp |grep 80 |awk '$1<10 {print $8}'|grep -v '0.0.0.0' |xargs -n1 -i{} /sbin/iptables -D INPUT -s {} -p tcp --dport 80 -j REJECT
/sbin/iptables -Z

for i in 1 2; do

        tail -n $n1 $logf >$tmplog

        cat $tmplog | grep 'submit' |awk '$6~/\/post.*php?/ {print $1}' |grep -v '192.168.0.' |grep -v '192.168.4.'|grep -v '127.0.0.'|grep -v '121.10.121.' |grep -v '124.238.249.' |grep -v '221.194.139.' | grep -v '124.238.246.' |grep -v '124.207.144.194'|grep -v '124.238.252.'|sort -n |uniq -c |sort -n |awk '$1>"'$n2'" {print $2}'>$ipf

        for ip in `cat $ipf`; do
           n=`grep $ip $tmplog |awk '{print $5}'|grep -v '-' |sort |uniq |wc -l`
           if [ $n -gt 2 ] ; then
                /sbin/iptables -I INPUT -s $ip -p tcp --dport 80 -j REJECT
                echo  $ip >>$badipf
           fi
        done
        sort -n $badipf |uniq >/tmp/tmp.log
        cat /tmp/tmp.log >$badipf
        sleep $n3
done

sleep $n3

done

bash快捷键

ctrl+p: 方向键 上 ↑
ctrl+n: 方向键下 ↓
ctrl+b: 方向键 ←
alt+f: 光标右移一个单词
ctrl+f :方向键 →
alt+b: 光标左移一个单词
ctrl+a:光标移到行首
ctrl+e:光标移到行尾
ctrl+k:清除光标后至行尾的内容。
ctrl+d: 删除光标所在字母;注意和backspace以及ctrl+h的区别,这2个是删除光标前的字符
ctrl+r:搜索之前打过的命令。会有一个提示,根据你输入的关键字进行搜索bash的history
ctrl+m : 输入回车
ctrl+i : 输入tab
ctrl+[ : 输入esc
ctrl+h:删除光标前一个字符,同 backspace 键相同。
alt + p 非增量方式反向搜索历史
alt + > 历史命令列表中的最后一行命令开始向前
ctrl+u: 清除光标前至行首间的所有内容。
ctrl+w: 移除光标前的一个单词
ctrl+t: 交换光标位置前的两个字符
ctrl+y: 粘贴或者恢复上次的删除
ctrl+l:清屏,相当于clear。
ctrl + xx 光标在行头与行尾进行跳转
alt+r 撤销当前行的所有内容
ctrl+z : 把当前进程转到后台运行
ctrl+s : 锁住屏幕
ctrl+q : 恢复屏幕
ctrl+v key: 输入特殊字符
alt + l 将当前光标处之后的字母转化成小写字母
alt + u 将当前光标处之后的字母转化成大写字母
ctrl + Alt + e 扩展命令行的内容(例如:ls => ls -l --color=tty)
ctrl+c:杀死当前进程, 输入模式下,中断输入的命令。
ctrl+d:退出当前 Shell

【求助】iptables重启后的问题

今天在VPS上测试一个iptables规则,很奇怪的问题,明明放行了22端口,防火墙启动后还是拦截了22端口,随后reboot了一下服务器,现在远程连接不上了,郁闷中.......,把shell脚本贴上来,希望大家帮忙看下哪里出了问题,谢谢额~~#!/bin/bash

ipt=/sbin/iptables

$ipt -F OUTPUT
$ipt -F FORWARD
$ipt -F INPUT
$ipt -X OUTPUT
$ipt -X INTPUT
$ipt -X FORWARD
$ipt -P INPUT DROP
$ipt -P OUTPUT ACCEPT
$ipt -P FORWARD DROP
$ipt -A INPUT -p tcp --dport 22 -j ACCEPT
$ipt -A INPUT -p tcp --dport 20 -j ACCEPT
$ipt -A INPUT -p tcp --dport 80 -j ACCEPT
$ipt -A INPUT -p tcp --dport 21 -j ACCEPT
$ipt -A INPUT -p udp --dport 22 -j ACCEPT
$ipt -A INPUT -p udp --dport 20 -j ACCEPT
$ipt -A INPUT -p udp --dport 80 -j ACCEPT
$ipt -A INPUT -p udp --dport 21 -j ACCEPT
$ipt -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$ipt -A INPUT -m state --state INVALID -j DROP
/sbin/service iptables save
/sbin/service iptables restart
exit 0
系统为centos 5.5
等iptables重启完成后,执行iptables -L看到也达到了预期的效果,input为drop,22  21  80 端口都在允许列表,cat /etc/sysconfig/iptables也看到了相应的规则,好几次了都是把自己挡在外边了,不知道是顺序还是哪里出了问题,希望大家可以指教,谢谢!!!

基于nginx日志,封蜘蛛IP


#! /bin/bash

grep 'spider' /home/logs/client/access.log |grep -v 'Baidu' |awk '{print $1}' >/root/ip1.txt  //日志中大部分蜘蛛都有spider的关键字,但是百度的不能封,所以过滤掉百度
grep 'YoudaoBot' /home/logs/client/access.log  | awk '{print $1}' >>/root/ip1.txt  // 封掉网易的有道
grep 'Yahoo!' /home/logs/client/access.log  | awk '{print $1}' >>/root/ip1.txt  //封掉雅虎
sort -n /root/ip1.txt |uniq  |sort |grep -v '192.168.0.' |grep -v '127.0.0.1'>/root/ip2.txt // 过滤掉信任IP
/sbin/iptables -nvL |awk '$1 <= 30 {print $8}' >/root/ip3.txt  // 如果一小时内,发包不超过30个就要解封
for ip in `cat /root/ip3.txt`; do /sbin/iptables -D INPUT -s $ip -j DROP ; done
/sbin/iptables -Z // 将iptables计数器置为0
for ip in `cat /root/ip2.txt`; do /sbin/iptables -I INPUT -s $ip -j DROP ; done

shell 将字符串反向显示

写一个shell脚本,将输入的字符串反转过来显示。即如果输入的字符串是”12345”,则输出的是”54321”。

vim  r.sh#!/bin/bash
str=$1;
len=${#str};
for((i=len;i>-1;i--))
do
echo -n "${str:i:1}"
done
echo
运行   
sh   r.sh  "12345"
结果:
54321

在0到9的数字前加一个零,大于9的不加

#! /bin/bash
for i in `seq 0 23`; do
        if [ $i -lt 10 ] ; then
                itask=`echo $i |sed 's/[0-9]/0&/'`
                echo $itask
        else itask=`echo $i`
                echo $itask
        fi
done