web-dev-qa-db-ja.com

CSVファイルのマージ:マージの代わりに追加

基本的には、いくつかのCSVファイルをマージしたいと思います。それを行うために次のスクリプトを使用しています。

paste -d , *.csv > final.txt

ただし、これは以前はうまくいきましたが、今回はうまくいきません。お互いの下にではなく、隣同士にデータを追加します。たとえば、次の形式のレコードを含む2つのファイル

CreatedAt   ID
Mon Jul 07 20:43:47 +0000 2014  4.86249E+17
Mon Jul 07 19:58:29 +0000 2014  4.86238E+17
Mon Jul 07 19:42:33 +0000 2014  4.86234E+17

合併したとき

CreatedAt   ID CreatedAt    ID
Mon Jul 07 20:43:47 +0000 2014  4.86249E+17 Mon Jul 07 18:25:53 +0000 2014  4.86215E+17
Mon Jul 07 19:58:29 +0000 2014  4.86238E+17 Mon Jul 07 17:19:18 +0000 2014  4.86198E+17
Mon Jul 07 19:42:33 +0000 2014  4.86234E+17 Mon Jul 07 15:45:13 +0000 2014  4.86174E+17
                                            Mon Jul 07 15:34:13 +0000 2014  4.86176E+17

これの背後にある理由が誰か知っていますか?または、レコードの下にマージを強制するために何ができますか?

21
user2233834

すべてのcsvファイルが同じ形式であり、すべて同じヘッダーで始まると仮定すると、次のような小さなスクリプトをすべてのファイルを1つだけに追加および1つだけを取得する)に記述できます。ヘッダーの時間

#!/bin/bash
OutFileName="X.csv"                       # Fix the output name
i=0                                       # Reset a counter
for filename in ./*.csv; do 
 if [ "$filename"  != "$OutFileName" ] ;      # Avoid recursion 
 then 
   if [[ $i -eq 0 ]] ; then 
      head -1  "$filename" >   "$OutFileName" # Copy header if it is the first file
   fi
   tail -n +2  "$filename" >>  "$OutFileName" # Append from the 2nd line each file
   i=$(( $i + 1 ))                            # Increase the counter
 fi
done

ノート:

  • head -1またはhead -n 1コマンドは、ファイルの最初の行(ヘッド)を出力します。
  • tail -n +2は、行番号2から始まるファイルの末尾を出力します(+2
  • テスト[ ... ]は、出力ファイルを入力リストから除外するために使用されます。
  • 出力ファイルは書き換えられます毎回。
  • コマンド cat a.csv b.csv > X.csvを使用すると、a.csvとb csvを1つのファイルに追加できます(ただし、ヘッダーを2回コピーします)。

pasteコマンドは、ファイルを片側に貼り付けます。ファイルの行に空白が含まれている場合は、上記でレポートした出力を取得できます。
の用法 -d ,paste commandは、フィールドをコンマで区切って定義します,、ただし、これは上記で報告したファイルの形式には当てはまりません。

catコマンドは、代わりにファイルを連結して標準出力に出力します。つまり、ファイルを1つずつ書き込みます。

参照する man headまたはman tail単一オプションの構文(一部のバージョンではhead -1その他の代わりにhead -n 1)...

38
Hastur

@wahwahwahahありがとうございます私はあなたのスクリプトを使用してnautilus-actionを作成しましたが、この変更でのみ正しく機能します:

#!/bin/bash

for last; do true; done

OutFileName=$last/RESULT_`date +"%d-%m-%Y"`.csv                       # Fix the output name

i=0                                       # Reset a counter
for filename in "$last/"*".csv"; do

 if [ "$filename" != "$OutFileName" ] ;      # Avoid recursion 
 then 
   if [[ $i -eq 0 ]] ; then 
      head -1  "$filename" > "$OutFileName" # Copy header if it is the first file
   fi
   tail -n +2  "$filename" >> "$OutFileName" # Append from the 2nd line each file
   i=$(( $i + 1 ))                        # Increase the counter
 fi
done
0
Andrea