我正在尝试更改由应用程序生成的文件,不幸的是,该文件经常包含空格。我已经设法让“echo”给我输出,如果复制粘贴到终端,该输出可以工作,但是当我尝试执行该命令时,它不起作用。我在看这答案,这之前对我有帮助,但即使是“${x}”语法在这种情况下似乎也不起作用。
#!/bin/sh
cd ~/Data
IFS=$'\n';for i in $(ls); do
echo "$i";
filename="$i"
date=$(date -n +%Y-%m-%d)
new_filename="$date$filename"
echo mv \'"${filename}"\' \'"${new_filename}"\'
mv \'"${filename}"\' \'"${new_filename}"\'
done;
答案1
主要问题是您循环输出ls
命令。请使用 glob *
:
#!/bin/sh
cd ~/Data
for i in *; do
echo "$i"
filename="$i"
date=$(date -n +%Y-%m-%d)
new_filename="${date}${filename}"
echo mv "${filename}" "${new_filename}"
mv -- "${filename}" "${new_filename}"
done
另外,我添加了--
为了mv
正确处理名称以-
.顺便说一句,我的date
命令没有-n
选项,但我保留它,因为您可能有不同的版本。
答案2
您遇到的另一个问题是 mv 行上还有多余的引号。当您使用 echo 打印将复制到 shell 的命令时,您需要将所有内容引用两次,一次用于此 shell,一次用于第二个 shell。只要文件名不以破折号开头或包含单引号,您的 echo mv 就可以正常工作。 mv只需要引用一次。
这是我重写你的代码片段的方法。
#!/bin/bash
cd ~/Data
date="$(date -n +%Y-%m-%d)"
for filename in *; do
echo "${filename}"
new_filename="$date$filename"
filename_e="$(echo "$filename"|sed -e 's!\('\''\)!\\\1!')"
new_filename_e="$(echo "$new_filename"|sed -e 's!\('\''\)!\\\1!')"
echo mv -- \'"${filename_e}"\' \'"${new_filename_e}"\'
mv -- "${filename}" "${new_filename}"
done;
此版本将正确重命名名称中包含任何字符的任何文件。唯一的限制是回显的命令可能会生成在名称中包含换行符的文件中不起作用的命令。
答案3
您只需处理文件名,\
在空格前添加转义字符即可。
filename=$(echo $i|sed 's/ /\\ /g')
mv $filename $new_filename