Chinaunix

标题: 如何保留最后的点,而替换其他的点和空格。 [打印本页]

作者: newoz    时间: 2014-02-17 18:16
标题: 如何保留最后的点,而替换其他的点和空格。
本帖最后由 newoz 于 2014-02-17 18:41 编辑

我有很多的文件,格式是:
  1. txt 2014.02.14.log
复制代码
txt 里还含有空格。我想将空格和. 都替换成 下划线 _, 但是不能全部替换,要保留最后一个,因为是后缀名。

我要的结果是:
  1. txt_2014_02_14.log
复制代码
我的系统不支持 rename 这个命令, 我想用sed得到新文件名,再用mv 改名,但是用sed产生新文件名的时候,始终无法控制好,要不就是只换了一个,要不就是替换所有的点和空格。
作者: Herowinter    时间: 2014-02-17 18:24
本帖最后由 Herowinter 于 2014-02-17 18:35 编辑

sed怎么直接修改文件名,配合mv?
ls出来的文件名有空格会被分成两半
真蛋疼
作者: newoz    时间: 2014-02-17 18:39
更新了一下,我想用sed得到新文件名,再用mv 改名。
作者: q1208c    时间: 2014-02-17 19:08
echo "txt 2014.02.14.log"| sed -e 's/ \([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/_\1_\2_\3/'
作者: zooyo    时间: 2014-02-17 19:28
提示: 作者被禁止或删除 内容自动屏蔽
作者: newoz    时间: 2014-02-17 19:33
回复 5# zooyo

这个很强。效果到位。 谢谢。
   
作者: runintostar    时间: 2014-02-17 20:25
  1. $ touch "txt 2014.02.14.log"
  2. $ ls
  3. txt 2014.02.14.log

  4. $ a="txt 2014.02.14.log"
  5. $ b=${a%.*}
  6. $ mv "$a" ${b//[ \.]/_}.${a##*.}
  7. $ ls
  8. txt_2014_02_14.log
复制代码

作者: elu_ligao    时间: 2014-02-17 22:25
  1. [redhat@localhost 2014]$ echo "txt 2014.02.14.log" | sed -r 's/[ .]/_/g;s/(.*)_(.*)/\1.\2/'
  2. txt_2014_02_14.log
复制代码

作者: yestreenstars    时间: 2014-02-17 23:38
本帖最后由 yestreenstars 于 2014-02-17 23:40 编辑

$ ls
txt 2014.02.14.log  txt 2014.02.15.log
$ IFS=$'\n';for file in `ls`;do mv $file `sed -r 's/[ .]/_/g;s/(.*)_/\1./' <<< $file`;done
$ ls
txt_2014_02_14.log  txt_2014_02_15.log
作者: q1208c    时间: 2014-02-18 08:16
我觉得还是先全替换了, 再换回来的方法更直接. 反正是扩展名, 只会出现一次. 这样应该更高效些.
作者: seesea2517    时间: 2014-02-18 09:17
  1. [seesea@UC ~]$ echo "txt aaa.bb.c.log" | sed -r 's/[ .]/_/g; s/_([^_]*$)/.\1/'
  2. txt_aaa_bb_c.log
复制代码

作者: Herowinter    时间: 2014-02-18 09:52
回复 9# yestreenstars
个人觉得这个才是楼主想要的。这里有两个问题,
一个是文件名中空格的处理,通过自定义IFS;
另一个才是对得到的文件名进行替换。


   
作者: rogantianwz    时间: 2014-02-18 09:56
  1. echo "txt 2014.02.14.log" | sed -r 's#[ .]#_#g;s#^(.*)(_)(.*)$#\1.\3#'
复制代码
先全替换了,然后再把最后那个_换成.
作者: rogantianwz    时间: 2014-02-18 10:03
TO 某人:正则表达式写的炫,写得精简、短小不代表就好!能正确运行、容易维护的表达式才是好的表达式!你写一个超牛逼的表达式通常会带给维护它的人无尽的痛苦!
作者: zhaopingzi    时间: 2014-02-18 10:13
回复 14# rogantianwz


    这方面维护人员负全责
作者: nathanielwen    时间: 2014-02-18 10:22
用sed这样一步就可以了吧?
  1. [root@localhost ~]# echo 'txt 2014.02.14.log' | sed 's/[. ]\([0-9]\)/_\1/g'
  2. txt_2014_02_14.log
复制代码

作者: rogantianwz    时间: 2014-02-18 16:06
回复 7# runintostar


    哎呀,哥呀,你太帅了
作者: nathanielwen    时间: 2014-02-19 10:10
在perl里找到一中环视的匹配方式。觉得还是很有意思的。
  1. [root@localhost ~]# echo 'txt 2014.02.19.log' | perl -pe 's/[ .](?!\w+$)/_/g'
  2. txt_2014_02_19.log
  3. [root@localhost ~]# echo 'txt a.b.c.log' | perl -pe 's/[ .](?!\w+$)/_/g'
  4. txt_a_b_c.log
  5. [root@localhost ~]# echo 'txt a.b.c.mp4' | perl -pe 's/[ .](?!\w+$)/_/g'
  6. txt_a_b_c.mp4
复制代码

作者: rogantianwz    时间: 2014-02-19 10:29
回复 18# nathanielwen


    不知道sed,awk支不支持环视,估计够呛!
作者: nathanielwen    时间: 2014-02-19 10:33
估计不支持吧,刚好今天看到《精通正则表达式》里面介绍了这个,刚好思路吻合。就贴上来了。用环视的话逻辑上是最好理解的:
除了后缀名相连的点号之外的点号及空格都替换为下划线。
回复 19# rogantianwz


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2