提议:两个实用的 shell 小程序

已查看 0 次
跳至第一个未读帖子

WANG Cong

未读,
2008年7月28日 11:42:252008/7/28
收件人 Xi You Linux Group、Li Lei、Dong Pu

既然某些同学不知道该写些什么shell小程序来练手,那么我提议两个,都是我实际中
遇到的,你写得好了我也拿来用用。:-)

1. 修复文件名。

我们知道,有些文件名字中经常含有空格,括号之类的字符,虽然合法,但对于我们
使用shell的人来说遇到这种名字往往比较头疼。因此,这个任务是把这些让我们感到
头疼的字符统统转化掉,比如说都转化成"_",例如:

文件名(不含引号): "hello world" 应该转化成"hello_world"

这是最简单的情况,你还应该考虑更多其它情况,比如文件名中含有换行。

另外,你应该提供很多选项供用户选择,比如替换的字符,我可以指定使用"-"而不是
“_”。越方便越好,请自由发挥。

2. 详细描述文件信息。

我们知道ls -l可以给出文件的详细信息,但那还不够友好,我想要列出更可读的信息,
比如:

$ prog foo.txt
File Name: foo.txt
Type: ASCII text
Owner: wangcong
Modify date: xxxxx
Permission of owner: read, write
Permission of group: read
Permission of others: read
....

等等。你还应该提供更多选项来控制这些输出。请自由发挥。


注1: 仅仅是提议,你们做不做和我没多大关系,我完全可以自己完成。
注2: 第1个比第2个难。

--
The opposite of love is not hate, but indifference.
--Elie Wiesel

李磊

未读,
2008年7月28日 12:29:202008/7/28
收件人 WANG Cong、Xi You Linux Group、Dong Pu
在 08-7-28,WANG Cong<xiyou.w...@gmail.com> 写道:
我也有2个想法:
1。自动拨号上网的shell(宿舍环境)

1。1 自动运行 wine ishare这个插件,并自动拨号,并且自动给别人开代理(用iptables)
1。2 环境为2个人(A和B)共用同一帐号,对于A来说。如果B给他开了代理,那么他可以上网,如果在上网的过程中B断线了。那么A需
要自己拨号,并且给B开代理。

这个过程要求用shell来完成,要使用户感觉不到曾经断网了。

2。自动寻找代理

在宿舍楼内,自动寻找代理主机,并且自动更换相关网卡信息,使用户可以上网。

即,只要用户运行这个shell,并且宿舍楼内有人开代理上网,那么用户就可以上网。

可能从道德上来说会令人鄙视下,但是我们可以实现它但不使用它。

Thomas X. Iverson

未读,
2008年7月28日 19:05:322008/7/28
收件人 李磊、WANG Cong、Xi You Linux Group、Dong Pu


2008/7/29 李磊 <lile...@gmail.com>

王大哥的第一道题目很早以前就自己试着去做过了,而且能够很好的实现批量处理,第二道很简单

--
Keep It Simple Stupid

http://blog.ghostunix.org

ghosTM55

吴雨龙

未读,
2008年7月28日 23:58:142008/7/28
收件人 西邮Linux兴趣小组、WANG Cong、李磊


---------- Forwarded message ----------
From: 吴雨龙 <wylon...@gmail.com>
Date: 2008/7/29
Subject: Re: [XiYouLinux] Re: 提议:两个实用的 shell 小程序
To: "Thomas X. Iverson" <t...@ghostunix.org>




2008/7/29 Thomas X. Iverson <t...@ghostunix.org>

大家的想法都挺不错的,至于我们小组将来做什么?我也做不了主,要和大家商量决定。

在这里谢谢大家的宝贵意见!





Kermit Mei

未读,
2008年7月29日 03:51:542008/7/29
收件人 Thomas X. Iverson、李磊、WANG Cong、Xi You Linux Group、Dong Pu
Thomas X. Iverson 写道:
>
> 王大哥的第一道题目很早以前就自己试着去做过了,而且能够很好的实现批量处
> 理,第二道很简单
能不能把你的给我发过来看看?我想用tr命令过滤文本,然后把文件名存到变量
中,但是当文件名中含有空格时就发生一个问题。下面是我的一点调试代码(并不
能完成全部功能):

File Edit Options Buffers Tools Insert Help
#!/bin/sh

while [ $# -ne 0 ]
do

if [ -w $1 ]
then
newname=$(echo $1|tr -c "[0-9][-][.][A-Z][_][a-z]" '-') ##把文件命中非正
规字符以‘-’代替,
##存到变量newname中
mv $1 $newname ##修改文件名
else
echo "Error! When access $filename.\n"
fi
shift
done

printf "Bye...\n"

这段失败的代码让我找到了两个我不懂的问题,望指教:

1.文件名中有空格,写入shell时是在空格前加入了一个 \ ,但是shell接受到它
后就会把这个空格去掉。那么,怎么在脚本中用变量表示含有空格的文件名?看下
面失败的代码,请帮我找出问题:
命令:> ls -l
总计 8
-rwxrw-rw- 1 kermit users 234 07-29 15:34 fnc.sh
-rw-r--r-- 1 kermit users 0 07-29 15:44 jj kg.txt
-rwxrw-rw- 1 kermit users 120 07-29 01:51 tstr.sh
命令:> F1=jj\ kg.txt
命令:> F11='jj\ kg.txt'
命令:> echo $F1 $F11
jj kg.txt jj\ kg.txt
命令:> mv $F1 1.txt
mv: 目标 “1.txt” 不是目录
命令:> mv $F11 1.txt
mv: 目标 “1.txt” 不是目录
命令:>

为什么用变量代表文件名再使用mv命令会失败?


2.注意这个指令: echo 123 4|tr -c "[0-9]" '@'
它的执行结果是: 123@4@

也就是说,在4的后面还有个东东,那个表示结尾的标识是什么?

Thank you!

Thomas X. Iverson

未读,
2008年7月29日 03:50:062008/7/29
收件人 Kermit Mei、李磊、WANG Cong、Xi You Linux Group、Dong Pu


2008/7/29 Kermit Mei <meiyan...@gmail.com>

那个脚本是去年写的了,几次重装后没有备份就没了,等我有空了重新写一个,到时候贴上来

Kermit Mei

未读,
2008年7月29日 04:03:242008/7/29
收件人 Thomas X. Iverson、李磊、WANG Cong、Xi You Linux Group、Dong Pu
Thomas X. Iverson 写道:
>
>
> 2008/7/29 Kermit Mei <meiyan...@gmail.com
> <mailto:meiyan...@gmail.com>>
补充一下,刚才无意间测试了一下,这个命令可以执行:
mv "$F1" 1.txt

加了引号和不加引号在这里有什么区别? 好像加了引号("")就可以把含有空格
及其转义字符的字符串表示成一个整体了?

李磊

未读,
2008年7月29日 04:03:222008/7/29
收件人 Kermit Mei、Thomas X. Iverson、WANG Cong、Xi You Linux Group、Dong Pu
在 08-7-29,Kermit Mei<meiyan...@gmail.com> 写道:
是的。我的看法和你说的是一样的。

Kermit Mei

未读,
2008年7月29日 04:14:592008/7/29
收件人 Thomas X. Iverson、李磊、WANG Cong、Xi You Linux Group、Dong Pu
Thomas X. Iverson 写道:
>
>
> 2008/7/29 Kermit Mei <meiyan...@gmail.com
> <mailto:meiyan...@gmail.com>>
> 1.文件名中有空格,写入shell时是在空格前加入了一个 \ ,但是shell接
> 受到它
> 后就会把这个空格去掉。那么,怎么在脚本中用变量表示含有空格的文件
> 名?看下
> 面失败的代码,请帮我找出问题:
> 命令:> ls -l
> 总计 8
> -rwxrw-rw- 1 kermit users 234 07-29 15:34 fnc.sh
> -rw-r--r-- 1 kermit users 0 07-29 15:44 jj kg.txt
> -rwxrw-rw- 1 kermit users 120 07-29 01:51 tstr.sh
> 命令:> F1=jj\ kg.txt
> 命令:> F11='jj\ kg.txt'
> 命令:> echo $F1 $F11
> jj kg.txt jj\ kg.txt
> 命令:> mv $F1 1.txt
> mv: 目标 "1.txt" 不是目录
> 命令:> mv $F11 1.txt
> mv: 目标 "1.txt" 不是目录
> 命令:>
>
> 为什么用变量代表文件名再使用mv命令会失败?
>
>
> 2.注意这个指令: echo 123 4|tr -c "[0-9]" '@'
> 它的执行结果是: 123@4@
>
> 也就是说,在4的后面还有个东东,那个表示结尾的标识是什么?
>
> Thank you!
>
>
> 那个脚本是去年写的了,几次重装后没有备份就没了,等我有空了重新写一个,
> 到时候贴上来
好,很期待。

把上面的代码改成下面这样就可以完成对文件名中空格的替换了:

#!/bin/sh

while [ $# -ne 0 ]
do

if [ -f "$1" -a -w "$1" ]


then
newname=$(echo $1|tr -c "[0-9][-][.][A-Z][_][a-z]" '-')

mv "$1" "$newname"


else
echo "Error! When access $filename.\n"
fi
shift
done

printf "Bye...\n"

但是有个Bug,就是第二个问题中所说的那个,最后老有一个多余的‘-’。这时什么
原因,怎么消除?


Kermit Mei

未读,
2008年7月29日 04:37:172008/7/29
收件人 Thomas X. Iverson、李磊、WANG Cong、Xi You Linux Group、Dong Pu
Kermit Mei 写道:

> 但是有个Bug,就是第二个问题中所说的那个,最后老有一个多余的‘-’。这时什么
> 原因,怎么消除?
呵呵,又大意了,下面的代码试试:

#!/bin/sh

while [ $# -ne 0 ]
do
if [ -f "$1" -a -w "$1" ]
then

newname=$(echo -n "$1"|tr -c "[0-9][-][.][A-Z][_][a-z]" '-')


mv "$1" "$newname"
else
echo "Error! When access $filename.\n"
fi
shift
done

printf "Bye...\n"

给echo 加个 -n 选项就搞定了,呵呵。

WANG Cong

未读,
2008年7月29日 04:42:582008/7/29
收件人 Kermit Mei、Thomas X. Iverson、Li Lei、Xi You Linux Group、Dong Pu
On Tue, Jul 29, 2008 at 04:37:17PM +0800, Kermit Mei wrote:
>Kermit Mei 写道:
>> 但是有个Bug,就是第二个问题中所说的那个,最后老有一个多余的‘-’。这时什么
>> 原因,怎么消除?
>呵呵,又大意了,下面的代码试试:
>
>#!/bin/sh
>
>while [ $# -ne 0 ]
>do
>if [ -f "$1" -a -w "$1" ]

为什么不支持目录?


>then
>newname=$(echo -n "$1"|tr -c "[0-9][-][.][A-Z][_][a-z]" '-')
>mv "$1" "$newname"

错误:
mv: good_name.txt' and good_name.txt' are the same file


>else
>echo "Error! When access $filename.\n"
>fi
>shift
>done
>
>printf "Bye...\n"
>
>给echo 加个 -n 选项就搞定了,呵呵。

--

Kermit Mei

未读,
2008年7月29日 05:07:052008/7/29
收件人 WANG Cong、Thomas X. Iverson、Li Lei、Xi You Linux Group、Dong Pu
WANG Cong 写道:
>
> 为什么不支持目录?
>
<snip>

> 错误:
> mv: good_name.txt' and good_name.txt' are the same file
>

恩,谢谢。再试试下面这个如何?

#!/bin/sh

while [ $# -ne 0 ]
do

if [ -w "$1" ]


then
newname=$(echo -n "$1"|tr -c "[0-9][-][.][A-Z][_][a-z]" '-')

if [ "$1" != "$newname" ]
then
mv "$1" "$newname"
fi


else
echo "Error! When access $filename.\n"
fi
shift
done

printf "Bye...\n"

这里还没有加入一些友好界面的注释,现测试一下功能上能否满足,还有无明显的Bug?
这是我的结果:


shell> ls -l
总计 8
-rw-r--r-- 1 kermit users 0 07-29 17:04 aaa
drwxr-xr-x 2 kermit users 4096 07-29 17:04 dir b
-rw-r--r-- 1 kermit users 0 07-29 17:04 file a
-rwxrw-rw- 1 kermit users 276 07-29 16:59 fnc.sh
shell> ./fnc.sh *
Bye...
shell> ls -l
总计 8
-rw-r--r-- 1 kermit users 0 07-29 17:04 aaa
drwxr-xr-x 2 kermit users 4096 07-29 17:04 dir-b
-rw-r--r-- 1 kermit users 0 07-29 17:04 file-a
-rwxrw-rw- 1 kermit users 276 07-29 16:59 fnc.sh
shell>
好像没什么大问题了吧,呵呵。


WANG Cong

未读,
2008年7月29日 06:45:562008/7/29
收件人 Kermit Mei、Thomas X. Iverson、Li Lei、Xi You Linux Group、Dong Pu
On Tue, Jul 29, 2008 at 05:07:05PM +0800, Kermit Mei wrote:
>WANG Cong 写道:
>>
>> 为什么不支持目录?
>>
><snip>
>> 错误:
>> mv: good_name.txt' and good_name.txt' are the same file
>>
>
>恩,谢谢。再试试下面这个如何?
>
>#!/bin/sh
>
>while [ $# -ne 0 ]
>do
> if [ -w "$1" ]
> then
> newname=$(echo -n "$1"|tr -c "[0-9][-][.][A-Z][_][a-z]" '-')
> if [ "$1" != "$newname" ]
> then
> mv "$1" "$newname"
> fi
> else
> echo "Error! When access $filename.\n"
> fi
> shift
>done
>
>printf "Bye...\n"
>
>这里还没有加入一些友好界面的注释,现测试一下功能上能否满足,还有无明显的Bug?

这还远不是我想要的,我还需要的功能是:

1. 对目录可选择(-R)进行递归操作,即修复所有子目录中的文件名。
2. 替换其它不想要的字符,比如“[”,"]","{","}","$","*"等。

韩新章

未读,
2008年7月30日 09:19:572008/7/30
收件人 西邮Linux兴趣小组
http://www.basicallytech.com/blog/?/archives/10-Shell-stuff-rename-multiple-files-on-the-command-line.html
这个网页说了批量改名称的方法,感觉不错
> --Elie Wiesel- 隐藏被引用文字 -
>
> - 显示引用的文字 -

WANG Cong

未读,
2008年7月30日 09:26:432008/7/30
收件人 njd...@gmail.com、Xi You Linux Group

>http://www.basicallytech.com/blog/?/archives/10-Shell-stuff-rename-multiple-files-on-the-command-line.html
>这个网页说了批量改名称的方法,感觉不错
>

感谢你的分享。

但是这明显与这个邮件的主题不符合,请选择合适的主题。:-)

回复全部
回复作者
转发
0 个新帖子