列の編集には awk または sed を使用します。下のパターンを印刷するには?

列の編集には awk または sed を使用します。下のパターンを印刷するには?

Sample Input:

title          role        subject
name-JOHN      student      math
school         state        NY
county         street       Phone
name-TOM       student      math
school         state        TX
county         street       Phone
name-LILLY     student      math
school         state        LA
county         street       Phone
name-ROSY      student      math
school         state        WA
county         street       Phone
garbage line 1
garbage line 2

Desired Output

JOHN     NY
TOM      TX
LILLY    LA
ROSY     WA

下部の2つのガベージラインは消えなければなりません。 AWkまたはSEDを使用したいですか?

私はSunオペレーティングシステムを実行しています。

答え1

GNUから提供sed

sed -n '/^name-/{s///;N;s/[a-z].*\s//p}' file
JOHN      NY
TOM       TX
LILLY     LA
ROSY      WA

GNUから提供awk

awk -F'[ -]+' '/name/{a=$2}/state/{print a,$3}' OFS='\t' file
JOHN    NY
TOM     TX
LILLY   LA
ROSY    WA

渡すgrep

grep -o '[[:upper:]]\{2,\}' file | paste - -
JOHN    NY
TOM     TX
LILLY   LA
ROSY    WA

答え2

ここに別の奇妙な方法があります。 (これは@Costasの醜いバージョンであることがわかります):

$ awk -F'[- ]' '($1~/name/){k=$2}($1~/school/){print k,$NF}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA

以下も使用できますgrep

$ grep -oP '^(name-\K\S+|school.*\s+\K.*)' file | paste - -
JOHN    NY
TOM TX
LILLY   LA
ROSY    WA

もちろん、特定の例では大文字のみを見つけることができます。

$ grep -Eo '[A-Z]{2,}' file | paste - -

またはパール:

$ perl -lne '$n=$1 if /^name-(\S+)/; /^school.*\s+(.+)/ && print "$n\t$1"' file

または別のパール:

$ perl -007ne 'print join "\n", (/name-(\S+?)\s.*?state\s+(..)\n/gsm)' file | paste - -

答え3

awk '/name/ {gsub(/name-/,""); printf "%s\t",$1} /school/ {print $3}' file
JOHN    NY
TOM     TX
LILLY   LA
ROSY    WA

答え4

明確に言えば、「古いawk」(/usr/bin/awk/)を使用していますか、それとも「新しいawk」(/usr/xpg6/bin/awk)を使用していますか?オンラインマンページ参照そしてGNU Awkヘルプページその違いは非常に明確に明らかになります。

「new」を意味する場合は、awk変数割り当てを使用してこれを実行できると仮定すると、-v次のことも考慮できます。

$ awk -v RS='name-' -v OFS='\t' 'NR>1{print $1,$6}' sample.txt
JOHN    NY
TOM     TX
LILLY   LA
ROSY    WA

名前と状態がそれぞれ最初の()フィールドと6番目の()フィールドとして解釈さ-v RS='name-'れるようにレコード区切り文字()を設定しました。その後、私たちも設定awk$1$6出力-v OFS='\t'必須フォーマットを実行するためのフィールド区切り記号()。条件はNR>1最初の行をスキップします。

編集する

awk 'BEGIN{RS="name-";OFS="\t"}NR>1{print $1,$6}' sample.txt

これは「古い」項目でも可能ですawk。テストしてみてください。awk「new」という元の提案を変更せずに維持します。

関連情報