bash脚本,修改文件

时间:2012-10-02 06:29:45

标签: linux bash shell file-io scripting

这是我的剧本:

#!/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

不幸的是,它只对列表中的最后一个文件执行此操作。它正在跳过所有其他人。我有一种感觉,这与缓冲或起泡或其他东西有关。我错过了什么?

3 个答案:

答案 0 :(得分:3)

您已在循环中定义file_read,然后从外部调用它。

应该是相反的方式!

您可能希望将一些值传递给file_read作为参数。

答案 1 :(得分: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

答案 2 :(得分:1)

不幸的是,它只对列表中的最后一个文件执行。

那是因为你只是在循环之后调用file_read一次。它只对最后一个文件执行它,因为变量iTHE_FILE2保留在循环的最后一次迭代中。

以下是awk解决方案:

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