2011-01-21 90 views
10

我在一堆具有前导点并因此被隐藏的目录中有一些文件。我想恢复并删除前导点。从文件名bash脚本中删除前导点

我是不成功的下列要求:

for file in `find files/ -type f`; 
do 
base=`basename $file` 
if [ `$base | cut -c1-2` = "." ]; 
then newname=`$base | cut -c2-`; 
dirs=`dirname $file`; 
echo $dirs/$newname; 
fi 
done 

的情况声明,失败:

[: =: unary operator expected 

此外,一些文件在他们身上有空间和文件返回它们分裂。

任何帮助,将不胜感激。

+0

当你说`恢复那个`,你的意思是重命名没有点的文件? – SiegeX 2011-01-21 19:41:42

+0

是的,去掉前导点 – Radek 2011-01-21 19:43:24

回答

21

从变量的起始处删除某些东西的最简单方法是使用${var#pattern}

$ FILENAME=.bashrc; echo "${FILENAME#.}" 
bashrc 
$ FILENAME=/etc/fstab; echo "${FILENAME#.}" 
/etc/fstab 

见bash手册页:

$ {参数#字}
$ {参数##字}

word被扩展为一个模式,就像路径名扩展一样。如果模式匹配参数值的开始,那么扩展结果为 带最短匹配模式(''#''大小写)或最长匹配模式(''## ''的情况)删除。

顺便说一句,有了更具选择性的find命令,你不需要做所有的努力工作。你可以有find只带有前导点匹配的文件:

find files/ -type f -name '.*' 

ETC技术一起,然后:

find files/ -type f -name '.*' -printf '%P\0' | 
    while read -d $'\0' path; do 
     dir=$(dirname "$path") 
     file=$(basename "$path") 
     mv "$dir/$file" "$dir/${file#.}" 
    done 

其他注意事项:

  1. 要正确地用空格处理文件名当你引用变量名时你需要引用变量名。写“$文件”,而不是只有$file

  2. 为了增强鲁棒性,-printf '\0'read -d $'\0'使用NUL字符作为分隔符,因此即使嵌入换行符'\n'的文件名也可以使用。

6
find files/ -name '.*' -printf '%f\n'|while read f; do 
     mv "files/$f" "files/${f#.}" 
done 
2
  1. 该脚本将与您 可以扔掉它的任何文件,即使他们有 空格,换行或其他恶意 字符他们的名字。
  2. 它的工作原理,无论隐藏的文件多少子目录深
  3. 不像其他的答案到目前为止,你 变更时, 给find的路径来改变脚本的其余部分

*注:我包含一个echo,以便您可以像干运行一样对其进行测试。如果您对结果满意,请删除单个echo

find . -name '.*' -exec sh -c 'for arg; do d="${arg%/*}"; f=${arg:${#d}}; echo mv "$arg" "$d/${f#.}"; done' _ {} +