N個の列と異なる数の行(行)を持つ.csvファイルがたくさんあります。;...;
長さが等しくなるように空行(Nセミコロン)をできるだけ多く追加したいと思います。最長ファイルの長さを手動で取得できますが、自動的に実行するのも良いでしょう。
たとえば、
私は持っている、
file1.csv
128; pep; 93; 22:22:10; 3; 11
127; qep; 93; 12:52:10; 3; 15
171; pep; 73; 22:26:10; 3; 72
file2.csv
128; pep; 93; 22:22:10; 3; 11
127; qep; 93; 12:52:10; 3; 15
121; fng; 96; 09:42:10; 3; 52
141; gep; 53; 21:22:10; 3; 62
171; pep; 73; 22:26:10; 3; 72
221; ahp; 93; 23:52:10; 3; 892
file3.csv
121; fng; 96; 09:42:10; 3; 52
171; pep; 73; 22:26:10; 3; 72
221; ahp; 93; 23:52:10; 3; 892
141; gep; 53; 21:22:10; 3; 62
しなければならない
file1.csv
128; pep; 93; 22:22:10; 3; 11
127; qep; 93; 12:52:10; 3; 15
171; pep; 73; 22:26:10; 3; 72
;;;;;
;;;;;
;;;;;
file2.csv
128; pep; 93; 22:22:10; 3; 11
127; qep; 93; 12:52:10; 3; 15
121; fng; 96; 09:42:10; 3; 52
141; gep; 53; 21:22:10; 3; 62
171; pep; 73; 22:26:10; 3; 72
221; ahp; 93; 23:52:10; 3; 892
file3.csv
121; fng; 96; 09:42:10; 3; 52
171; pep; 73; 22:26:10; 3; 72
221; ahp; 93; 23:52:10; 3; 892
141; gep; 53; 21:22:10; 3; 62
;;;;;
;;;;;
答え1
コメントに提案をいただいた@Sparhawkに感謝します。これに基づいて更新します。
#!/bin/bash
emptyLine=;;;;;;;
rr=($(wc -l files*pattern.txt | awk '{print $1}' | sed '$ d'))
max=$(echo "${rr[*]}" | sort -nr | head -n1)
for name in files*pattern.txt;do
lineNumber=$(wc -l < $name)
let missing=max-lineNumber
for((i=0;i<$missing;i++));do
echo $emptyLine >> $name
done
done
まあ、エレガントでも効率的ではありません。実際、これは数秒かかり、少量のデータを考慮すると永遠のように聞こえます。それでも動作します。
#!/bin/bash
emptyLine=;;;;;;;
rr=($(wc -l files*pattern.txt | awk '{print $1}' | sed '$ d'))
max=$(echo "${rr[*]}" | sort -nr | head -n1)
for name in $(ls files*pattern.txt);do
lineNumber=$(cat $name | wc -l )
let missing=max-lineNumber
for((i=0;i<$missing;i++));do
echo $emptyLine >> $name
done
done
ファイルの一覧表示に使用できるパターンがある場合は、ファイルがあるディレクトリにこのファイルを配置します。files*pattern.txt
答え2
@myradioの答えが改善されました。
ループ内に作成された部分はawk
はるかに高速でなければなりません。
max=$(wc -l file*.csv | sed '$ d' | sort -n | tail -n1 | awk '{print $1}' )
for f in file*.csv; do
awk -F';' -v max=$max \
'END{
s=sprintf("%*s",FS,"");
gsub(/ /,"-",s);
for(i=NR;i<max;i++)
print s;
}' "$f" >> "$f"
done
-F
ファイルの正しいフィールド区切り文字を設定できます(ここ-F';'
)。
このセクションでは、(=フィールド区切り文字)s=sprintf();gsub();
の正しい数を動的に設定します(FS
渡す)。必要に応じて、
単に別の静的コンテンツに置き換えることができます。print ";;;;;"
答え3
各ファイルの行を一度だけ計算するには、次のようにします。
wc -l *csv |sort -nr| sed 1d | {
read max file
pad=$(sed q "$file"|tr -cd ";") # extract separators from first record
while read lines file ; do
while [ $((lines+=1)) -le $max ] ; do
echo "$pad" >> "$file"
done
done
}
ファイル名に改行があるとループに問題が発生しますsort
が、while read
通常のスペースを含むファイル名を処理できます。