簡體   English   中英

在找到第一個圖案sed的基礎上,找到圖案並打印行awk grep

[英]find a pattern and print line based on finding the first pattern sed, awk grep

我的檔案很大。 通用的是打破每個部分示例的主機名:

HOSTNAME:host1
   data 1
     data here
   data 2 
      text here
   section 1
      text here
   part 4  
      data here
   comm = 2

HOSTNAME:host-2

   data 1
     data here
   data 2 
      text here
   section 1
      text here
   part 4  
      data here
   comm = 1

以上打印

如您在上方看到的,在每個部分之間,還有其他部分按具有特定值的關鍵字或行細分

我喜歡使用oneliner為每個部分打印主機名,然后在每個主機名部分下打印我要提取的行

你能幫忙嗎? 我現在正在使用grep -C 10 HOSTNAME | gerp -C模式,但這假設每個部分中有10行。 這不是執行此操作的最佳方法。 有人可以顯示更好的方法嗎? 我還需要能夠在找到的每種模式下打印多行。 因此,如果我找到data1並且它下面還有其他行,我想抓取並打印它們

所以命令的輸出就像

grep -C 10 HOSTNAME | grep data 1  
grep -C 10 HOSTNAME | grep -A 2 data 1 

HOSTNAME:Host1

   data 1  

HOSTNAME:Hoss2

   data 1 

在Grep旁邊,我使用此sed命令來打印我的輸出

sed -r '/HOSTNAME|shared/!d' filename

這個sed命令的唯一問題是,它僅打印其中包含共享模式和HOSTNAME的行。 我還需要在與共享模式匹配的行下指定我要打印的行數。 因此,我喜歡打印HOSTNAME,並在共享的第二個搜索模式下給出我希望打印的行數。

謝謝

這是一個sed twoliner:

sed -n -r '/HOSTNAME/ { p }                                  
          /^\s+data 1/ {p }' hostnames.txt 

打印( p

  • 當該行包含HOSTNAME時
  • 當該行以某些空白( \\s+ )開頭,后跟您的搜索條件( data 1
  • 不打印非數學行(由於sed -n選項)

編輯:一些備注:

  • 這已經在Linux下用GNU sed 4.2.2進行了測試
  • 如果您的sed版本不支持-r ,則將第二個模式替換為/^.*data 1/
  • 我們可以將所有東西壓扁;

綜上所述,這里是一行的修訂版本,不需要擴展的正則表達式(即,沒有-r ):

sed -n '/HOSTNAME/ { p } ; /^.*data 1/ {p }' hostnames.txt

awk來救援!

$ awk -v lines=2 '/HOSTNAME/{c=lines} NF&&c&&c--' file

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

打印lines包括模式匹配在內的lines數,跳過空行。

如果要指定輔助關鍵字而不是行數

$ awk -v key='data 1' '/HOSTNAME/{h=1; print} h&&$0~key{print; h=0}' file

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

OP的要求似乎還不清楚,但是以下內容與對要求的一種解釋是一致的,更重要的是,該程序沒有特殊要求,並且可以輕松地修改代碼以滿足各種要求。 特別是,兩個搜索模式(HOSTNAME模式和“數據1”模式)都可以輕松地進行參數化。

主要思想是打印指定小節中的所有行,或至少打印一定數量的行,直至達到某個限制。

如果在子節中應打印的行數上有限制,請為限制指定一個值,否則將其設置為0。

awk -v limit=0 '
  /^HOSTNAME:/ { subheader=0; hostname=1; print; next}
  /^ *data 1/  { subheader=1; print; next }
  /^ *data /   { subheader=0; next }          
  subheader && (limit==0 || (subheader++ < limit)) { print }'

給定問題中提供的行,輸出將是:

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

(是的,我知道awk程序中的變量“主機名”當前尚未使用,但我將其包括在內以使其易於添加測試,從而滿足有關識別子標題的前提條件的某些顯而易見的要求。)

sed -n -e'/主機名/,+ p'-e'/雙工/,+ p'最簡單的方法是組合兩個sed命令..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM