免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7393 | 回复: 4
打印 上一主题 下一主题

路径含空格问题求解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-21 21:52 |只看该作者 |倒序浏览
正在看各置顶贴,还未找到答案。但因为比较急,所以先把问题发在这。

假设输入下列代码
read a ; for i in $a ; do echo $i ; echo 2 ; done
当提示用户输入时,输入*
那么当然会将当前目录下的文件打印出来,假设当前目录下只有a1,a2,a3等3个文件,那么得到
*(用户输入)
a1
2
a2
2
a3
2
这没有问题。
假设当前目录为/path/to/foo,将用户输入改为/path/to/foo/*,那么得到
/path/to/foo/*(用户输入)
/path/to/foo/a1
2
/path/to/foo/a2
2
/path/to/foo/a3
2
也没问题。
假设当前目录为/path/to/f oo(注意那个空格),问题来了:
输入/path/to/f oo/*或者/path/to/f\ oo/*,都得到
...(用户输入)
/path/to/f
2
oo/*
2
显然是空格的问题。
于是修改代码为
read a ; for i in "$a" ; do echo $i ; echo 2 ; done
再次输入/path/to/f oo/*或者/path/to/f\ oo/*,都得到
...(用户输入)
/path/to/f oo/*
2
$a不再展开。可以理解,但是问题是如何求全?即又要展开、又要兼顾空格的可能性。

在最后一种情况下,即
read a ; for i in "$a" ; do echo $i ; echo 2 ; done
如果当前目录为/path/to/foo,不再含空格,用户输入*,将得到
*(用户输入)
a1 a2 a3
2
何解?如果我在前面讲的够清楚,这显然不是我的需求,因为$i似乎只取了一次值。如何修正?

问题概括:
需要$i历遍用户输入的所有文件(用户可能利用通配符指定文件,需要能自动被识别并展开),但要照顾到路径包含空格的可能性。

写的比较罗嗦,希望讲清楚了问题。

论坛徽章:
0
2 [报告]
发表于 2007-06-21 22:30 |只看该作者
输入
"/path/to/f oo/*"

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
3 [报告]
发表于 2007-06-22 10:02 |只看该作者
try

  1. #!/usr/bin/sh
  2. read a
  3. b=`echo "$a" | sed 's/ /\\\\ /g'`
  4. eval ls -l $b | awk -F: '{print substr($2,4)}'
复制代码

论坛徽章:
0
4 [报告]
发表于 2007-06-22 10:35 |只看该作者
已经用
oldifs=$IFS
IFS=
......(在for那句话里不要带引号了)
IFS=$oldifs
的方式解决了问题。

但是仔细想想,空格是暂时没问题了,那些特殊字符呢?
我发现Linux对文件名可用的字符的要求似乎很松散,随便试了几个shell的元字符,居然都可以当作文件名用。
看来要求用户尽量用字母、数字、下划线、点作文件名,可以省下很多麻烦。

但从程序设计者的角度出发,是要求用户适应程序,还是尽量让程序适应各种用户,似乎是个很值得思考的命题,呵呵。

论坛徽章:
0
5 [报告]
发表于 2007-06-24 21:42 |只看该作者
解释一下
再次输入/path/to/f oo/*或者/path/to/f\ oo/*,都得到
...(用户输入)
/path/to/f oo/*
2
$a不再展开。可以理解,但是问题是如何求全?即又要展开、又要兼顾空格的可能性。

在最后一种情况下,即
read a ; for i in "$a" ; do echo $i ; echo 2 ; done
如果当前目录为/path/to/foo,不再含空格,用户输入*,将得到
*(用户输入)
a1 a2 a3
2
何解?如果我在前面讲的够清楚,这显然不是我的需求,因为$i似乎只取了一次值。如何修正?


在用read读入用户自己输入的参数的时候,IFS在其中起了很大的作用
当输入/path/to/f oo/* 的时候,shell会根据IFS的值先进行分割,而默认情况下IFS就是空格表格符号和回车了,所以这时read a实际上得到的是两个分开的参数。然后shell又会进行展开重组,因为是两个参数,即使shell碰到*,不能展开了。

而后你(worc)说用"IFS="这种方法解决了问题,也是这个道理,因为这是空格已经不是分隔符了。
test
  1. >pwd
  2. /u/hong
  3. >mkdir "f    oo" #three space
  4. >cd "f    oo"
  5. >touch file1 file2
  6. >read a ; for i in "$a" ; do echo $i ; echo 2 ; done
  7. /u/hong/f   oo/*
  8. /u/hong/f oo/*  #变成一个空格了
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP