一、题目
指定目录from_dir下面有一些csv文件,要求找出这一类文件,并把文件内的Tab符替换成逗号,并将文件的扩展名改为.tsv并存放于to_dir目录。请写一个shell脚本。
二、思路
1.找出扩展名为.csv的文件可以用find命令,注意是文件。
find $from_dir/ -name *.csv -type f
2.将文件内的Tab符替换为逗号,使用sed。
sed -i 's/\t/,/g' $Name
3.把文件扩展名修改为tsv并存放于to_dir。
mv $Name $to_dir/$str
三、实现
1.建立实验文件,文件内包括Tab符。
#!/bin/bash
for FILE in aa bb cc ab bc ac
do
echo -e '\t'>>$FILE.csv
done
2.具体实验脚本。
方案1:
#!/bin/bash
from_dir="/root"
to_dir="/opt"
for Name in `find $from_dir/ -name "*.csv" -type f`
do
sed -i 's/\t/,/g' $Name
File=$(echo $Name|awk -F "/" '{ print $NF }')
echo $File>FileName
sed -i 's/.csv/.tsv/g' FileName
str=`cat FileName`
mv $Name $to_dir/$str
rm -rf FileName
done
方案2:
#!/bin/bash
from_dir="/root"
to_dir="/opt"
cd $from_dir
for File in `find -name "*.csv" -type f`
do
sed -i 's/\t/,/g' $File
done
find -name "*.csv" -type f -exec mv {} $to_dir/{} \;
rename .csv .tsv $to_dir/*.csv
简直不要太简单!
3.执行。
方案1执行结果:
[root@ChatDevOps ~]# source Script.sh
[root@ChatDevOps ~]# ll
总用量 8
-rw-r--r--. 1 root root 215 5月 7 19:50 Script.sh
-rw-r--r--. 1 root root 79 5月 7 18:52 test.sh
[root@ChatDevOps ~]# ll /opt/
总用量 24
-rw-r--r--. 1 root root 2 5月 7 19:50 aa.tsv
-rw-r--r--. 1 root root 2 5月 7 19:50 ab.tsv
-rw-r--r--. 1 root root 2 5月 7 19:50 ac.tsv
-rw-r--r--. 1 root root 2 5月 7 19:50 bb.tsv
-rw-r--r--. 1 root root 2 5月 7 19:50 bc.tsv
-rw-r--r--. 1 root root 2 5月 7 19:50 cc.tsv
[root@ChatDevOps ~]# cat /opt/aa.csv
,
目标实现,继续寻找其他方案。
方案2执行结果:
[root@ChatDevOps ~]# source Script.sh
[root@ChatDevOps ~]# ll /opt/
总用量 24
-rw-r--r--. 1 root root 4 5月 7 20:31 aa.tsv
-rw-r--r--. 1 root root 4 5月 7 20:31 ab.tsv
-rw-r--r--. 1 root root 4 5月 7 20:31 ac.tsv
-rw-r--r--. 1 root root 4 5月 7 20:31 bb.tsv
-rw-r--r--. 1 root root 4 5月 7 20:31 bc.tsv
-rw-r--r--. 1 root root 4 5月 7 20:31 cc.tsv
[root@ChatDevOps ~]# cat /opt/aa.tsv
,
再想一想,看看怎么写方案3,哈哈!
四、总结
1.在回答这道题的时候,容易陷入一种一个语句实现全部功能的怪圈,没理解清楚题目,文件名中是不可能有Tab符的。这道题目前可能还有Bug,我再考虑一下,其他实现方式我也再想想。
2.方案2其实有个缺陷,万一$to_dir之前就存在.csv的文件呢?都全部被我们重命名了!需要改进一下,可以创建一个临时目录,把find到的文件先移动到这个空目录,然后重命名,最后再移到$to_dir。当然也可以用find命令加exec再次处理,判定修改时间小于2分钟,才重命名。