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」という元の提案を変更せずに維持します。