2011-08-30 46 views
4

我想循环通过目录中的所有文件。如何使用bash和sed操纵文件名?

我想在每个文件上做一些东西(将其转换为xml,不包含在示例中),然后将文件写入新的目录结构。

for file in `find /home/devel/stuff/static/ -iname "*.pdf"`; 
do 
    echo $file; 
    sed -e 's/static/changethis/' $file > newfile +".xml"; 
    echo $newfile; 
done 

我想要的结果是:

$文件=>/home/devel/stuff/static/2002/hello.txt

$的newfile =>/home/devel/stuff/changethis/2002/hello.txt.xml

如何做我不得不改变我的sed线?

回答

2

你想改变文件名吗?然后

for file in /home/devel/stuff/static/*/*.txt 
do 
    echo "Moving $file" 
    mv "$file" "${file/static/changethis}.xml" 
done 

请确保/home/devel/stuff/static/*/*.txt是您在使用脚本之前所需的。

+0

没有。我试图获取文件名,追加“.xml”并将其放在diff目录中 – Mark

+0

@Mark为您更新了答案 –

+0

@Mu Qiao:您的通配符扩展将会丢失静态目录中的任何.txt文件。 find命令不会。 –

5

如果您需要重命名多个文件,我会建议使用rename命令:

# remove "-n" after you verify it is what you need 
rename -n 's/hello/hi/g' $(find /home/devel/stuff/static/ -type f) 

,或者如果你没有做rename试试这个:

find /home/devel/stuff/static/ -type f | while read FILE 
do 
    # modify line below to do what you need, then remove leading "echo" 
    echo mv $FILE $(echo $FILE | sed 's/hello/hi/g') 
done 
0
find ... | while read file; do 
    newfile=$(basename "$file").xml; 
    do something to "$file" > "$somedir/$newfile" 
done 
1

第一,您必须根据初始文件的名称创建新文件的名称。显而易见的解决方案是:

newfile=${file/static/changethis}.xml 

其次,你必须确保新的路径存在或创建它,如果没有:

mkdir -p $(dirname $newfile) 

然后,你可以做一些与你的文件:

doSomething < $file > $newfile 
1

由于可能导致您的命令行超载,因此我不会执行for循环。命令行的长度有限,如果你超载了它,它会简单地删除多余的数据而不给你任何警告。它可能工作,如果你的查找返回100文件。它可能工作,如果它返回1000个文件,但它可能会失败,如果你的查找返回1000个文件,你永远不会知道。

处理此问题的最佳方法是将查找管道传送到while读取语句中作为glenn jackman

sed命令仅适用于标准输入和文件,但不能在文件名,所以如果你想你的Munge时间的文件名,你就必须做这样的事情:

$newname="$(echo $oldname | sed 's/old/new/')" 

得到文件的新名称。 $()构造执行命令并将命令的结果放在STDOUT上。

所以,你的脚本就会是这个样子:

find /home/devel/stuff/static/ -name "*.pdf" | while read $file 
do 
    echo $file; 
    newfile="$(echo $file | sed -e 's/static/changethis/')" 
    newfile="$newfile.xml" 
    echo $newfile; 
done 

现在,因为你重命名文件的目录,你必须确保你做你的移动或复制之前所在的目录:

find /home/devel/stuff/static/ -name "*.pdf" | while read $file 
do 
    echo $file; 
    newfile="$(echo $file | sed -e 's/static/changethis/')" 
    newfile="$newfile.xml" 
    echo $newfile; 

    #Check for directory and create it if it doesn't exist 
    $dirname=$(dirname "$newfile") 
    if [ ! -d "$dirname" ] 
    then 
     mkdir -p "$dirname" 
    fi 

    #Directory now exists, so you can do the move 
    mv "$file" "$newfile" 
done 

请注意用引号来处理文件名中有空格的情况。

顺便说一句,而不是做这样的:

if [ ! -d "$dirname" ] 
then 
    mkdir -p "$dirname" 
fi 

你可以这样做:

[ -d "$dirname"] || mkdir -p "$dirname" 

||手段,执行下面的命令只有在测试是不正确的。因此,如果[-d“$ dirname”]是错误语句(该目录不存在),则运行mkdir

当您看到shell脚本时,这是一个相当常见的快捷方式。

0
OUTPUT="$(pwd)"; 
for file in `find . -iname "*.pdf"`; 
do 
    echo $file; 
    cp $file $file.xml 
    echo "file created in directory = {$OUTPUT}" 
done 

这将创建一个名称whatyourfilename.xml一个新的文件,hello.pdf创建将hello.pdf.xml新的文件,基本上它会创建.XML结尾处附加一个新的文件。

请记住,上述脚本在目录/home/devel/stuff/static/中查找文件名与匹配find命令的匹配字符串(在本例中为* .pdf)的文件,并将其复制到当前工作目录。

此特定脚本中的find命令仅查找文件名以.pdf结尾的文件如果要为文件名以.txt结尾的文件运行此脚本,则需要将find命令更改为此find /home/devel/stuff/static/ -iname "*.txt",