0

これが私のスクリプトです:

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

残念ながら、リストの最後のファイルに対してのみ実行します。他のすべてをスキップしています。これは、バッファリングやグロビングなどと関係があると感じています。私は何が欠けていますか?

4

3 に答える 3

3

ループの内側を定義file_readし、外側から呼び出しました。

逆のはずです!

一部の値をパラメータとしてに渡すことをお勧めしfile_readます。

于 2012-10-02T06:39:25.497 に答える
1

関数は必要ありませんfile_read。そのコードを直接forループに入れるだけです。

また、なぜシェルのコマンドを使用して、それを各行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
于 2012-10-02T07:00:09.797 に答える
1

残念ながら、リストの最後のファイルに対してのみ実行します。

file_readこれは、ループ後に 1 回だけ呼び出しているためです。i変数とTHE_FILE2ループの最後の反復から残っているため、最後のファイルに対してのみ実行されます。

ここにawk解決策があります:

awk -f - *.csv << 'EOD'
BEGIN { OFS = FS = "," }
{
    out = FILENAME "-2.csv"
    print $1,$2,",",$3,$4 >> out
}
EOD
于 2012-10-02T09:19:23.570 に答える