0

キーワードに該当する世帯データを抽出します。

Z1/NEW "THE_PALM" 769 121003   1545     
NEW HOUSE IN
SOMETHING SOMETHING

SN                HOUSE            CLASS
FIRST             PSD93_PU         1579

CHAIRS
WOOD
SILVER SPOON
GREEN GARDEN



Z1/OLD "THE_ROSE" 786 121003   1343     
NEW HOUSE OUT
SOMETHING NEW

SN                HOUSE            CLASS
FIRST_O           PSD1000_ST       1432

CHAIRS
WOOD
GREEN GARDEN
BLACK PAINT


Z1/OLD "The_PURE" 126 121003   3097    
NEW HOUSE IN
SOMETHING OLD

SN                HOUSE            CLASS
LAST_O            JD4_GOLD         1076

CHAIRS
SILVER SPOON

非常に大きなサイズのファイルがあります。各説明の最後に、家に関するアイテムのリストがあります。を含む住宅に対応して、 dataと dateのようにIDSILVER SPOONを抽出したい。私は次のことを試しました:HOUSEPSD93_PU121003

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=7 a=0 s="SILVER" infile > outfile

しかし問題は、キーワードの上の行数SILVERが非常にランダムであるため、解決策がわからないことです。

4

3 に答える 3

0

sed の使用:

sed -n -e 's/^Z1[^"]*"[^"]*"[ \t]*[0-9]*[ \t]*\([0-9]*\).*/\1/p'
       -e '/^SN[ \t]*HOUSE/ { n; s/^[^ \t]*[ \t]*\([^ \t]*\).*/\1/p }'

まず、指定した内容のみを印刷するようにオプションを指定sedして呼び出します。-n

最初のコマンドは、特定のパターンを検索して日付を抽出します。パターンは次のもので構成されます。

  1. ^Z1: 文字列「Z1」で始まる行。
  2. [^"]*: 二重引用符ではない 0 個以上の文字
  3. ": 二重引用符
  4. [^"]*: 二重引用符ではない 0 個以上の文字
  5. [ \t]*: タブまたはスペースの 0 個以上の文字
  6. [0-9]*: ゼロ以上の数字
  7. [ \t]*: タブまたはスペースの 0 個以上の文字
  8. \([0-9]*\): ゼロ以上の数字。バックスラッシュのかっこは、一致をキャプチャするために使用されます。一致は補助変数に格納されます\1
  9. .*: 0 個以上の文字。実質的に行末まですべての文字をスキップします。

\1この一致した行は、キャプチャされたコンテンツである日付を保持する に置き換えられます。コマンドのp後に、結果を出力するよう sed に指示します。

2 行目には、グループ化された 2 つのコマンド (中かっこの内側) が含まれているため、中かっこの前の「アドレス」でのみ実行されます。アドレスはパターンであるため、パターンに一致するすべての行で実行されます。このパターンは、「SN」で始まり、その後に一連のスペースまたはタブが続き、その後に文字列「HOUSE」が続く行で構成されます。

パターンが一致すると、まずn入力から次の行をロードする次のコマンドを実行します。次に、日付を抽出するのと同様の方法で、新しい行から ID を抽出します。一致する代替パターンは次のとおりです。

  1. ^[^ \t]*: スペースまたはタブ (空白) 以外の 0 個以上の文字で始まる文字列。
  2. [ \t]*: 次に、ゼロ個以上のスペースおよび/またはタブのシーケンスがあります。
  3. \([^ \t]*\): 一連の非空白文字がキャプチャされます
  4. .*: 残りの文字はスキップされるように一致します。

置換はキャプチャされた ID になり、再び sed にそれを出力するように指示します。

これにより、日付を含む行が出力され、その後に ID を含む行が続きます。形式の行が必要な場合ID dateは、次のように、sed の出力を別の sed インスタンスにパイプできます。

sed -n -e [...] | sed -e 'h;n;G;s/\n/ /'

この sed インスタンスは、次の操作を実行します。

  1. 行を読み取り、hコマンドはその行をホールド スペース (補助バッファー) に格納するよう指示します。
  2. コマンドで次の行を読み取りnます。
  3. get コマンドは、ホールド スペースのG内容をパターン スペース (作業バッファー) に追加するため、ID 行の後に日付行が続きます。
  4. 最後に、改行文字をスペースに置き換えて、行が 1 行に結合されるようにします。

これが役立つことを願っています=)

于 2012-10-15T11:10:27.447 に答える
0

レコードが 2 ~ 3 行の空白行で区切られていて、家庭用品の前の行間隔が一定である場合は、次のように使用できますGNU awk

awk -r 'BEGIN { RS="\n{3}\n*"; FS="\n" } /SILVER SPOON/ { split($1, one, OFS); split($6, two, OFS); print two[2], one[4] }' file.txt

結果:

PSD93_PU 121003
JD4_GOLD 121003
于 2012-10-15T12:38:06.503 に答える
0

それぞれの新しい家がZ1

 $ awk '$1 ~ /^Z1/ { date=$4; id=""; f=0; next; } \
        $1 == "SN" { f=1; next; }                 \
        f == 1 { id=$2; f=0; next; }              \
        $1" "$2 == "SILVER SPOON" { print id,date }' file 

つまり、新しい家で、すべての変数をリセットし、SNが一致する場合は日付を取得し、次の行には ID が含まれます「 SILVER SPOON」が見つかったid場合は行から取得し、 見つからない場合は新しい家満たされ、変数がリセットされます。iddate

与えられたデータでテストします:

$ awk '$1 ~ /^Z1/ { date=$4; id=""; f=0; next; } $1 == "SN" { f=1; next; } f == 1 { id=$2; f=0; next; } $1 == "SILVER SPOON" && $2 == "SPOON" { print id,date }' file 
PSD93_PU 121003
JD4_GOLD 121003

: 誰かが方法と if$1 == "SILVER" && $2 == "SPOON"を 1 つのステートメントにマージできることを知っていれば、それは素晴らしいことです :) -- のように:$1,$2 == "SILVER SPOON"

編集:それはで行うことができます$1" "$2 == "SILVER SPOON"
スペースを省略して実行することもできます$1$2 == "SILVERSPOON"が、$2空で$1文字列全体が含まれていたり、SILVERSPOONだっ$1たりしても一致します。したがって、 のスペースは厳密な一致として機能します。$2

于 2012-10-15T09:36:12.317 に答える