2012-10-02 138 views
0

這裏是我的腳本:bash腳本,修改一個文件

#!/bin/bash 


for i in *.csv 
do 
     echo "i: $i" 
     THE_FILE2="$i-2.csv" 

     file_read() 
     { 
       lineno=0 
       while read line 
       do 
         echo $line | awk -F, '{print $1","$2",,,"$3","$4}' 
         ((lineno++)) 
       done 
     } < $i > $THE_FILE2 
     echo "the_file2: $THE_FILE2" 
     echo "end" 
done 

file_read 

輸出:

i: 2992.csv 
the_file2: 2992.csv-2.csv 
end 
i: 5415.csv 
the_file2: 5415.csv-2.csv 
end 
i: csa.csv 
the_file2: csa.csv-2.csv 
end 
i: loc.csv 
the_file2: loc.csv-2.csv 
end 
i: visa.csv 
the_file2: visa.csv-2.csv 
end 

$ ls 
2992.csv  csa.csv  transform.sh visa.csv-2.csv 
5415.csv  loc.csv  visa.csv 

不幸的是,它只做它在列表的最後一個文件。它跳過所有其他人。我有一種感覺,這與緩衝或通配或某事有關。我錯過了什麼?

+1

你爲什麼要讀一行文件行腳本? Awk默認爲你做。 'awk -F''{print $ 1','$ 2',,,'$ 3','$ 4}'$ i> $ THE_FILE2'可以做你想要的(未經測試) – Bernhard

回答

3

您已在循環內定義了file_read,然後從外部調用它。

它應該是相反的!

您可能需要將部分值傳遞給file_read作爲參數。

+1

我會完全擺脫這個函數案件。 – Bernhard

+0

在上面給出的例子中,這可能是一個很好的解決方案 - 它足夠小,它可以保持內聯而不會混淆代碼太多。 – John3136

1

不需要file_read功能。只需將該代碼直接放在for循環中即可。

此外,爲什麼你使用shell的read命令,然後將它回顯到每條線的新命令awk?您可以將整個文件重定向到awk,它會自動讀取每行。

而你正在遞增lineno,但沒有用於任何事情。如果你需要的行號沒有顯示,你可以使用awk的NR變量。

for i in *.csv 
do 
     echo "i: $i" 
     THE_FILE2="$i-2.csv" 
     awk -F, '{print $1","$2",,,"$3","$4}' < $i > $THE_FILE2 
     echo "the_file2: $THE_FILE2" 
     echo "end" 
done 
1

不幸的是,它只做它在列表的最後一個文件。

這是因爲您只在循環後調用file_read一次。它僅對最後一個文件執行,因爲變量iTHE_FILE2仍然是循環的最後一次迭代。

這裏是一個awk解決方案:

awk -f - *.csv << 'EOD' 
BEGIN { OFS = FS = "," } 
{ 
    out = FILENAME "-2.csv" 
    print $1,$2,",",$3,$4 >> out 
} 
EOD