2012-02-10 95 views
3

我試圖在一堆* .txt文件中替換一個字符串。我熟悉這個命令:如何替換文件中的字符串並將它「另存」爲另一個文件

find "$folder" -type f -name '*.txt' -exec sed -i 's/REPLACEFROM/REPLACETO/g' {} \; 

但是,這個(按per標誌)取代了字符串inplace。

我希望做的是保持所有原始文件的完整和「保存」的修改過的文件的「文件1 - renamed.txt」,「文件2-renamed.txt」,...

有什麼最快和最優雅的方式來做到這一點?也許perl?

我相信這是非常基本的,但它似乎很難。 :)

在此先感謝您的幫助。

回答

3

隨着SED,您可以使用

sed -i.back 

這樣一來,原來的文件將被移動到* .back

或者用這個片段是最接近你的問題:

find "$folder" -type f -name '*.txt' -exec bash -c ' 
    cp "$1" "${1%.*}-renamed.txt" 
    sed -i 's/REPLACEFROM/REPLACETO/g' "${1%.*}-renamed.txt" 
' -- {} \; 
+0

Perl也有一個'-i'開關,它的工作方式相同:'-i.bak'將使原始文件保存爲附加在文件名後面的'.bak'。 – 2012-02-10 21:42:31

0

這不完全是一個單線,但它應該的技巧(和IMO更容易閱讀):

use strict; 
use warnings; 

while(@ARGV) 
{ 
    my $file=shift; 
    open(my $read,"<",$file) or die $!; 
    my $output_file=$file . "_renamed"; 
    if($file=~/^(.+)\.txt$/) 
    { 
    $output_file=$1 . "-renamed.txt"; 
    } 

    open(my $write,">",$output_file) or die $!; 

    while(<$read>) 
    { 
    chomp; 
    s/REPLACEFROM/REPLACETO/g; 
    print $write "$_\n"; 
    } 
    close($read); 
    close($write); 
} 
2

用Perl,你可以嘗試這樣的事:

find "$folder" -name '*.txt' | 
    xargs perl -ne 'open NEW, ">>$ARGV.new"; s/from/to/g; print NEW' 

這將新的文件保存爲old-name.txt.new。如果您確實需要「old-name-renamed.txt」格式,則可能需要更改它。還要注意,在每次執行oneliner之後它會追加到新文件。

當然,使用-i選項(... perl -i.old -pe 's/from/to/g')然後將文件批量重命名爲所需的名稱格式會比較容易,所以這種解決方案只有在原始文件不可寫入時纔有意義。

0

這可能會爲你工作:

find "$folder" -type f -name '*.txt' | 
parallel sed 's/REPLACEFROM/REPLACETO/g' ">" {.}-renamed.txt 
0

我已經發布了一個answer這裏,但另一種解決方案越過我的腦海今天:

for f in (find "$folder" -name '*.txt'); do perl -ne 's/from/to/g' $f > "$f.new"; done 

再次,它會保存修改的內容爲「OLD- name.txt.new「(如果你願意,你可以將它改爲... > "$(basename $f)-renamed.txt" ...)。

這個答案比我以前的答案要好,因爲它不需要爲每一個新行打開相同的文件。

相關問題