0

Unix を学んでいて、このテーブルを並べ替えたい:

Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984

そして、次のようにフォーマットします。

Rain,0264,little stone,11-09-1982
Susan,1261,Menlo park,12-13-1989
Zack,1594,columbus,02-04-1984
Mark,2218,Palo Alto,04-23-1984
Alice,2368,columbus,03-11-1988
Ted,2368,Portland,06-11-1992
Xiao,2571,Carson,07-06-1975

キーと値のペア (キー:値) でキーを除外し、awk と並べ替えを使用して ID で並べ替えたいと考えています。

これを行うには、どのコマンドを使用しますか?

4

9 に答える 9

3

これは次のように簡単です。

awk -F: '{gsub(/,[^:]*:/,",");print $2}' You_file| sort -t, -k 2,2n

以下でテスト:

> cat temp
Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984
>

今実行:

> awk -F: '{gsub(/,[^:]*:/,",");print $2}' temp | sort -t, -k 2,2n
Rain,0264,little stone,11-09-1982
Susan,1261,Menlo park,12-13-1989
Zack,1594,columbus,02-04-1984
Mark,2218,Palo Alto,04-23-1984
Alice,2368,columbus,03/11/1988
Ted,2368,Portland,06-11-1992
Xiao,2571,Carson,07/06/1975
于 2012-10-29T07:11:35.693 に答える
2

grep を使用して値を見つけ、貼り付けて行を再構成し、もちろん並べ替えます。

grep -oP '(?<=:).*?(,|$)' filename | paste -d "" - - - - | sort -n -t, -k2

値にコンマがないことを前提としています。

于 2012-10-29T12:16:05.113 に答える
2

入力データで「誕生日」のつづりが間違っていることが最終的にわかるまで、これを理解するのにしばらく時間がかかりました。

これを完全に独り占めして、データを実際のデータとして解析できます。

awk -F, '
  BEGIN {
    fmt="%s,%s,%s,%s\n";
  }

  {
    for (i=1;i<=NF;i++) {           # walk through the fields...
      split($i,a,":");              # split each one at the colon, save to array
      v[tolower(a[1])]=a[2];        # need tolower() as "Hometown" is inconsistent
    }
    split(v["bithday"],b,/[-\/]/);  # regex here handles your inconsistent divider
    v["bithday"]=sprintf("%s-%s-%s",b[3],b[2],b[1]);
    printf(fmt,v["name"],v["id"],v["hometown"],v["bithday"]);
  }
' input.txt | sort -t, -k2

これは各行を通過し、フィールドをカンマで分割し、キーと値の組み合わせを配列に格納し、「誕生日」形式を調整して出力します。(より賢明な日付形式を選択したことに注意してください。)

しかし、単純なパターン マッチングを行う方が簡単かもしれません。

sed -Ene 's/^[[:alpha:]]+://;s/,[[:alpha:]]+:/,/g;s/([0-9]{2}).([0-9]{2}).([0-9]{4})$/\3-\2-\1/;p' input.txt \
| sort -t, -k2

これにより、同じ結果が生成されますが、コードが少なくなります。入力データでさらに興味深いことを行う必要がある場合は、もちろん awk が最適です。

ああ、私sedは FreeBSD から来ているので、-Eオプションを使用して ERE を取得します。Linux または GNU sed の他のプロバイダーを使用している場合は、おそらく を に置き換えることができ-Eます-r

于 2012-10-28T21:22:20.387 に答える
1

awkが必要ですか?そうでない場合:

  1. Vimキー文字列を削除するために使用します:%s/[a-z]*://gi
  2. 並べ替えを使用して並べ替えます。sort -t , -k 2 file

AWKが必須の場合は、キーを失うことなくソートするためにこれを考えますが、@Aifの答えも素晴らしいです。

編集:@Aifの正規表現と@Ghotiのコメントのおかげで改善されました。現在、置換のためのVimコマンドは、マスターYodaが言うように、正規表現とキーケースを使用し、テキストは「重要ではありません」。

于 2012-10-28T20:03:13.033 に答える
1

私が見つけた最も簡単な方法は、 を使用awkして出力を再フォーマットし、使用する新しい列を追加し、再度sort使用してその列を非表示にすることです。awk

$ cat test.dat
Name:Alice,ID:2368,Hometown:columbus,bithday:03/11/1988
Name:Ted,ID:2368,Hometown:Portland,bithday:06-11-1992
Name:Mark,ID:2218,Hometown:Palo Alto,bithday:04-23-1984
Name:Xiao,ID:2571,hometown:Carson,bithday:07/06/1975
Name:Rain,ID:0264,hometown:little stone,bithday:11-09-1982
Name:Susan,ID:1261,Hometown:Menlo park,bithday:12-13-1989
Name:Zack,ID:1594,Hometown:columbus,bithday:02-04-1984

$ cat test.dat| awk -F, '{ gsub(/[a-zA-Z]+:/, ""); print $2,$0; }' | sort | awk '{ $1=""; print; }'
 Rain,0264,little stone,11-09-1982
 Susan,1261,Menlo park,12-13-1989
 Zack,1594,columbus,02-04-1984
 Mark,2218,Palo Alto,04-23-1984
 Alice,2368,columbus,03/11/1988
 Ted,2368,Portland,06-11-1992
 Xiao,2571,Carson,07/06/1975

-Fデリミタを指定することです(ここでは,)。次に、列名 (つまり、後に続く任意の文字:) を削除し、最後に ID 列と、書き換えられた行全体を表示します。次に を使用sortします。デフォルトでは、ソート キーが最初の列であると想定され、awk各行の 2 番目の部分のみが表示されます。

編集:都市のスペースを考えると、awkで出力の問題がありました。簡単にするために、最初の変数 (非表示にする列) を再割り当てし、行全体を出力します。

于 2012-10-28T19:11:02.397 に答える
1

FS と OFS を頭の中にあるものに設定し、必要なフィールドを出力して、並べ替えるだけです。

$ awk -F'[:,]' -v OFS=, '{print $2,$4,$6,$8}' file | sort -t, -k2n
Rain,0264,little stone,11-09-1982
Susan,1261,Menlo park,12-13-1989
Zack,1594,columbus,02-04-1984
Mark,2218,Palo Alto,04-23-1984
Alice,2368,columbus,03/11/1988
Ted,2368,Portland,06-11-1992
Xiao,2571,Carson,07/06/1975
于 2012-10-29T14:18:17.707 に答える
1

を使用する 1 つの方法を次に示しGNU awkます。

awk 'BEGIN { FS="[,:]"; OFS="," } { for (i=2; i<=NF; i+=2) printf (i!=NF) ? $i OFS : $i ORS | "sort -t, -nk2" }' file.txt

結果:

Rain,0264,little stone,11-09-1982
Susan,1261,Menlo park,12-13-1989
Zack,1594,columbus,02-04-1984
Mark,2218,Palo Alto,04-23-1984
Alice,2368,columbus,03/11/1988
Ted,2368,Portland,06-11-1992
Xiao,2571,Carson,07/06/1975
于 2012-10-29T00:32:07.103 に答える
0

必要に応じてフォーマットした後 (私はあなたが持っていることを理解しています)、データを にパイプすることにより、2 番目の列で並べ替えることができますsort -t, -k2

実際にまだ行っていない場合、最も簡単な方法の 1 つはsed 's/[[:alnum:]]*://g'.

したがって、コマンド全体は次のようになります

sed 's/[[:alnum:]]*://g' table.csv | sort -t, -k2
于 2012-10-28T21:39:07.740 に答える
-1

猫temp.txt | awk -F",|:" '{print $2","$4","$6}' | 並べ替え -t、-k2n

于 2013-08-03T04:12:04.183 に答える