2010-09-19 57 views
2

我已经有了一个足够简单的问题,但没有指导还有通过论坛或bash。问题如下:bash文件名开头匹配

我想在与* .h或* .cpp匹配的目录中的每个文件名中添加前缀字符串。但是,如果前缀已经应用到文件名,请不要再应用它。

为什么下面不工作是什么,还有待想通了:

for i in *.{h,cpp} 
do 
if [[ $i!="$pattern*" ]] 
then mv $i $pattern$i 
fi 
done 

回答

2

你可以试试这个:

for i in *.{h,cpp} 
do 
if ! (echo $i | grep -q "^$pattern") 
# if the file does not begin with $pattern rename it. 
then mv $i $pattern$i 
fi 
done 
+0

是的,这样做会起作用 - 虽然它有在shell中显示grep输出的副作用,stdin) - 将需要关闭 – Display 2010-09-19 18:11:53

+0

@Display; grep -q会为你做到这一点。尽管这是一个相当耗费资源的解决方案。谢天谢地,回声是一种内置的,所以它会减少一些时间。直接检查字符串将是更可取的。 – falstro 2010-09-19 18:14:08

+0

是的。我宁愿不使用回声。 – Display 2010-09-19 18:15:43

0
for i in *.{h,cpp}; do 
    [ ${i#prefix} = $i ] && mv $i prefix$i 
done 

不完全符合你的剧本,但它应该工作。如果没有前缀,该检查返回true(即,如果$ i,前缀“前缀”被移除,等于$ i)。

+0

$ {i#prefix}应该是$ {i#$ prefix}。 但是其他工作。谢谢。 – Display 2010-09-19 18:10:08

+0

@Display;不,它应该是$ pattern,但我指的是字面前缀。 – falstro 2010-09-19 18:12:53

+0

上面使用'前缀'两个地方的$模式,是的。 – Display 2010-09-19 18:17:44

1
#!/bin/sh 
pattern=testpattern_ 
for i in *.h *.cpp; do 
    case "$i" in 
    $pattern*) 
     continue;; 
     *) 
     mv "$i" "$pattern$i";; 
    esac 
done 

这个脚本会在任何Posix的shell中运行,而不是仅仅是bash。 (我不确定你的问题是“为什么这不工作”或“我该如何做这项工作”,所以我猜想它是第二个。)

2

其他人已经显示替换比较的工作;我会刺探为什么原始版本没有。原始前缀测试存在两个问题:比较运算符(!=)与其操作数之间需要有空格,而星号用引号引起(意思是字面匹配,而不是通配符)。修复这些问题,并且(至少在我的测试中)它按预期工作:

if [[ $i != "$pattern"* ]]