私はbashシェルを使用しています。行番号を持つファイルがある場合
1
4
7
9
最初の要素が数字で、その後にテキスト文字列が続く別の行ファイル
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
awk
最初の数字が最初のファイルに属している場合にのみ、2番目のファイルから行を抽出するコマンドをどのように書くことができますか?上記の例では、次のような結果が出ることが予想されます。
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
私はこれを試しました
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
しかし、3番目のファイルでは何も生成されません。
答え1
,
2番目のファイルはカンマで区切られているため、コマンドラインオプションを使用してawkフィールド区切り文字を-に設定する必要があります。-F
awk -F, 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
またはFS
組み込み変数を介して:
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file FS=, /tmp/second_file > /tmp/third_file
後者のアプローチを使用すると、最初のファイルがコンマで区切られず、複数のフィールドがある場合を処理できます。
答え2
使用幸せ(以前のPerl_6)
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] == any(@a);' file.csv
#OR
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] ~~ any(@a);' file.csv
RakuはPerlファミリーのプログラミング言語です。数値リストを取得してBEGIN
配列に保存するとき@a
。その後、フラグは-ne
自動的に印刷せずにコマンドラインからファイルを読み込みます(awk
同様の動作)。
ここで、行はテーマ変数($_
)(カンマの上)として読み取られ、split
最初の要素()が得られます。数値等価演算子(最初のコード例)またはRakuのスマートマッチ演算子を使用して[0]
これらの要素を比較します。演算子の右側にある配列はノードになります。条件が成立すると、条件に応じて行が出力されます。==
~~
@a
any()
if
put
入力例:
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
出力例(nbr_list.txt
1,4,7,9で構成されるファイルを使用):
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
結合ポイントは自動的にスレッド化されるので興味深いです。上記の問題については、one()
コネクタがより効率的に動作する可能性があります。
別の方法はセットを使用することです。つまり、行番号をsに変換することSet
ですInt
。データは行単位で読み取られ、各最初の列は強制的に変換され、セットの要素であることがInt
確認されます。(elem)
infix(elem)
または infix 、 (Unicode 記号) は、次のコードで使用できます。∈
~$ raku -ne 'BEGIN my $set1 = Set.new("nbr_list.txt".IO.lines.map: *.Int); \
.put if $_.split(",").[0].Int (elem) $set1;' file
Rakuセットには固有の値しか含めることができないため(つまり、入力は「固有」です)、2番目の例ではファイルの重複エントリを削除します"nbr_list.txt"
。これは実際にOPが望むものかもしれません。
https://docs.raku.org/type/Junction
https://docs-stage.raku.org/type/Junction
https://raku.org
答え3
これを「結合」と呼びます。 coreutilsにはjoin
テキストファイルをリンクするツールがあります。
join -t, -j1 --nocheck-order first_file second_file
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
説明する:
-t,
- フィールド区切り文字としてカンマを使用します。-j1
- 最初のフィールドを追加--nocheck-order
- Joinを使用するにはファイルをソートする必要がありますが、数値ソートは好きではありません。したがって、辞書の順序をチェックし、「10」が前に来る「9」について文句を言うのを防ぎます。両方のファイルの最初の列が同じアルゴリズムを使用してソートされている限り、まだ機能します。