2011-08-30 48 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",