フォルダ内のすべてのcsvファイルのデータ行の末尾にヘッダーフィールドとファイル名を追加します。

フォルダ内のすべてのcsvファイルのデータ行の末尾にヘッダーフィールドとファイル名を追加します。

フォルダ内のすべてのcsvファイルのすべての行の末尾にファイル名(拡張子なし)を追加したいと思います。すべてのファイルに同じヘッダーがあります。

私のフォルダにa.csvとb.csvという2つのファイルがあるとしましょう。

a.csvには次のものが含まれます(最初の行はヘッダーです)。

num1,num2,num3  
1,2,3

b.csvには次のものが含まれます(最初の行はヘッダーです)。

num1,num2,num3    
4,5,6

.csvファイルが必要です(最初の行はヘッダーです)。

num1,num2,num3,filename  
1,2,3,a

b.csvファイルが必要です。 (最初の行はヘッダーです。)

num1,num2,num3,filename  
4,5,6,b

Unixではどうすればいいですか?

答え1

for file in *.csv
do
  filename=${file%.csv}
  sed -i -e "1s/\$/,filename/; 2,\$s/\$/,$filename/" "$file"
done
  1. *csv現在のディレクトリの各ファイルを繰り返します。
  2. 末尾を削除してファイル名テキストを準備する.csv
  3. -isedを使用してファイルを適切に編集します。
    1. 1行目のみ行末を検索し、text(escaped $)に置き換えます,filename
    2. 2行目からファイルの終わり($)まで、行の終わり($)を検索してコンマと準備されたファイルの名前に置き換えます。

答え2

OPを正しく理解したら、「理想的な」解決策は次のものを使用することです(拡張子のない行1、拡張子のある残りの行)GNU awk

gawk -F, -i inplace \
'BEGIN {
    OFS=",";
 }
 {
    if(FNR==1)
        name = gensub(/^(.*)\..*/, "\\1", "g", FILENAME);
    else
        name = FILENAME;

    print $0, name;
 }' *.csv

、ハンドル、および-F割り当ては、OFS=","入力フィールドと出力フィールドの区切り文字をに設定します,

-i inplaceファイルの現在のレコードを切り捨て、現在の出力をファイルに書き込むことを意味します。

gensub組み込みは拡張子なしでファイル名を保存し、printステートメントは必要な修正履歴を印刷します。

答え3

次のコマンドを使用してくださいミラーmlr)はCSVファイルを読み込み、filename現在のファイルのパス名(コマンドラインに指定)を含み、.csv最後に削除する新しいフィールドを各ファイルに追加します。

mlr -I --csv put '$filename = sub(FILENAME,"\.csv$","")' a.csv b.csv

を使用すると、-I現在の場所でファイルを変更でき、各ファイルは個別に処理されます。残りは慣れておく必要があり、awkボーナスは名前でフィールドを参照できることです。新しいフィールド名を割り当てると、フィールドが生成されます。

Millerは、引用が必要なすべてのフィールドを自動的に引用します。

$ cat a.csv
num1,num2,num3
1,2,3
$ cat b.csv
num1,num2,num3
4,5,6
$ mlr -I --csv put '$filename = sub(FILENAME,"\.csv$","")' a.csv b.csv
$ cat a.csv
num1,num2,num3,filename
1,2,3,a
$ cat b.csv
num1,num2,num3,filename
4,5,6,b

関連情報