我正在尝试重命名包含空格的文件。 IFS = $'\ n'实际上用作FOR循环现在可以处理带空格的文件名。不幸的是,DIR中的所有.csv文件都插入到变量FL中,这导致错误。变量FL有没有办法一次处理一个文件,同时它还处理文件名中的间距?
脚本:
IFS=$'\n'
for FL in `ls -1 ${DIR}/*.csv`
do
FL_DP=`echo ${FL}`
FL_RN=`echo ${FL_DP} | tr -d '[:blank:]'`
mv ${FL_DP} ${FL_RN}
done
结果:
+ IFS=$\n
+ ls -1 test _1.csv test _2.csv
++ echo test _1.csv
test _2.csv
FL_DP=test _1.csv
test _2.csv
++ echo test _1.csv
test _2.csv
FL_RN=test_1.csv
test_2.csv
+ mv test _1.csv
test _2.csv test_1.csv
test_2.csv
mv: cannot access test _1.csv
test _2.csv
预期结果:
+ ls -1 test _1.csv test _2.csv
++ echo test _1.csv
FL_DP=test _1.csv
++ echo test _1.csv
FL_RN=test_1.csv
mv test _1.csv test_1.csv
您可能只需要使用空格引用变量。但@Cyrus对解析ls输出有一个很好的观点。诱人的时候,它应该被认为是人类可读的数据。
这是你如何在没有ls的情况下做到这一点:
for f in "$dir"/*.csv; do mv -i "$dir/$f" "$dir/${f// /}"; done
在FL_DP中从`backticks`更改为"quotes"
不要解析ls,只需使用for file in dirname..
IFS=$'\n'
for FL in {DIR}/*.csv
do
FL_DP="${FL}"
FL_RN=`echo ${FL_DP} | tr -d '[:blank:]'`
mv ${FL_DP} ${FL_RN}
done
这是一个使用find,while和read的例子:
find . -type f | while
read filename
do
echo "$filename"
done
以下是如何将上述结构应用于您的特定问题:
find $DIR -name '*.csv' -type f | while
read filename
do
mv "$filename" ${filename/ /}
done
你可以找到find
和awk
命令
find . -name "*.csv" -printf "mv \"%f\" |\"%f\" \n" | awk -F"|" ' { gsub(" ","",$2); print } '
样品测试
$ ls -1 *csv
scores.csv
'test _1.csv'
'test _2.csv'
$ find . -name "*.csv" -printf "mv \"%f\" |\"%f\" \n" | awk -F"|" ' { gsub(" ","",$2); print } '
mv "scores.csv" "scores.csv"
mv "test _1.csv" "test_1.csv"
mv "test _2.csv" "test_2.csv"
$
这里printf使用%f标识符打印文件名,只需添加一个管道并打印文件名2次。
我在这里使用了管道,因为它不会出现在文件名中。现在将结果传递给带有“|”的awk命令as delimiter和使用gsub()函数替换空格。
最终结果可以再次传递给ksh来执行它们
希望这可以帮助