.csv
顧客情報を含む多くのファイルがあります。これらすべてのファイルで、FIRSTNAME
この列の横に追加の列を追加したいと思いますFULLNAME
。名前は最初の単語をインポートして生成できますFULLNAME
。
ジャン・ポールのように、2つの単語の名前はありません。最後の列では、フィールドテキストにカンマが使用されます。
入力する
COMPANY,FULLNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
期待される出力
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
awk、sed、または他のものを使用してこれをどのように実行できますか?
答え1
CSVをサポートするユーティリティの使用ミラー( mlr
):
mlr --csv \
put '$FIRSTNAME = sub($FULLNAME," .*","")' then \
reorder -f COMPANY,FULLNAME,FIRSTNAME file
...質問にあるデータに基づいて、結果は次のようになります。
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Millerのこれらの使用は、フィールドの最初の空白文字の後のすべての項目をFIRSTNAME
削除する正規表現ベースの置換を使用して新しいフィールドを作成することから始まります。FULLNAME
COMPANY
新しいフィールドは最後にレンダリングされるため、最初のフィールドが、、、FULLNAME
およびこの順序でなるようにフィールドが並べ替えられます。FIRSTNAME
残りのフィールドは元の順序を維持します。
using 式の代わりに with 関数を使用してput
フィールド値をスペースに分割し、最初の結果文字列を選択できます。sub()
put
splitnv()
FIRSTNAME
mlr --csv \
put '$FIRSTNAME = splitnv($FULLNAME," ")[1]' then \
reorder -f COMPANY,FULLNAME,FIRSTNAME file
よりきれいな出力のために:
$ mlr --icsv --opprint --barred put '$FIRSTNAME = splitnv($FULLNAME," ")[1]' then reorder -f COMPANY,FULLNAME,FIRSTNAME file
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
| COMPANY | FULLNAME | FIRSTNAME | EMAIL | FUNCTION | CITY | INDUSTRY | COMMENT |
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
| Company name | Firstname Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, work |
| Company name | Firstname infix Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, workhome, work |
| Company name | Firstname infix infix2 Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, work |
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
答え2
使用幸せ(以前のPerl_6)
~$ raku -MText::CSV -e 'my @a = csv(in => $*IN); \
my @b = [Z] @a>>[0..1], @a>>[1].map(*.words.[0]), @a>>[2..*]; \
@b = @b>>.[*;*]>>.Array; @b[0][2] = "FIRSTNAME"; \
csv(in => @b, out => $*OUT);' file
OPがCSV出力全体を二重引用符で囲むことを望む場合、これはおそらく最も簡単なアプローチです(挿入されたカンマおよび/またはスペースを含む引用フィールドがある場合はRFC4180を参照)。
Perl(5) モジュールはText::CSV_XS
高い評価を受けており、長年の作成者/メンテナンス者が RakuText::CSV
モジュール (H. Merijn Brand, 個人コミュニケーション) を開発しました。ここで、RakuのText::CSV
機能はIO操作、特に参照の最後の列に制限されています。それ以外の場合は、上記の列操作は標準のRaku配列を使用して行われます。ただし、このコードの利点は、$*IN
STDINを使用する二重引用符で囲まれたファイルパスを代わりに使用できることです。
上記では、ファイルは@a
最初の行から配列として読み取られ、2行目ではゼロでインデックス付けされたword
列1の最初の項目を取り出し、ゼロでインデックス付けされた列2に割り当て、残りの行を@b
1行ずつ配置します。 3行目は、いくつかの管理タスク(配列の平面化、@b
要素変更可能化、列ヘッダーの変更)を実行します。最後に、ファイルは4行目に出力されます。
入力例:
COMPANY,FULLNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
出力例(上記):
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
"Company name","Firstname Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, work"
"Company name","Firstname infix Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, workhome, work"
"Company name","Firstname infix infix2 Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, work"
実際、最後の列を再参照するだけでも、より多くの作業が必要です。上記の最後の行をcsv(in => @b, out => $*OUT)
次に置き換えます。
.join(",").put for @b[0]; \
.join(",").put for [Z] @b[1..*]>>.[0..*-2]>>.join(","), @b[1..*]>>.[*-1].map(*.raku);'
出力例(修正コード例):
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
https://datatracker.ietf.org/doc/html/rfc4180
https://github.com/Tux/CSV/blob/master/doc/Text-CSV.md
https://raku.org
答え3
使用sed
$ sed -E '2,$s/[^,]*,([^ ]*) [^,]*,/&\1,/;1s/([^,]*,){2}/&FIRSTNAME,/' input_file
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"