
フォルダ内のすべての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
*csv
現在のディレクトリの各ファイルを繰り返します。- 末尾を削除してファイル名テキストを準備する
.csv
-i
sedを使用してファイルを適切に編集します。- 1行目のみ行末を検索し、text(escaped
$
)に置き換えます,filename
。 - 2行目からファイルの終わり(
$
)まで、行の終わり($
)を検索してコンマと準備されたファイルの名前に置き換えます。
- 1行目のみ行末を検索し、text(escaped
答え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