`sed`を使用して正確な文字列を一致させる方法は?しかし、その一部ではありません。


8

以下のような入力ファイルFILE1.TXTがあります。


11 id1  
12  
13 AGE = 20  
14 NAME = NAME1  
15  
16 id2  
17  
18 AGE = 30  
19 NAME = NAME2  
.  
.  
.  
110 idXYZ  
111  
112 AGE = AGEXYZ  
113 NAME = NAMEXYZ  
114  
115 idZZZ  
116

特定のIDに属するすべてのフィールドを検索して、NAMEの値を取得したい

IDをループ処理して、必要に応じて各IDに対して以下のコマンドを作成しました。

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'

ここでの問題は、出力NAME1を取得し、それに加えてNAMEXYZも取得することです

NAME1のみを取得し、NAMEXYZを取得しないようにするには何を変更する必要がありますか?

回避策として、以下のコマンドが機能します。

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'|head -1

「スイッチ」はありますか、それとも何か不足していますか?

回答:


3

検索したい行番号がわかっている場合(Qが示唆しているように)、不要な行と一致しないように正規表現を厳しくします。

たとえば、次のように変更します。

sed -n '/11/,/14/p' | grep NAME | awk -F "= " '{print $2}'

sed -n '/^11 /,/^14 /p' | grep NAME | awk -F "= " '{print $2}'

^特定の行番号が一致するだろうという数を保証した後、行の先頭と空間にマッチします、そしてあなたは、不要なブロックを処理しません。


それは役に立ちます。しかし、どうすれば一致でき^(random no of spaces)11ますか?
Vinay

1
@VinayChalluruの使用sed -n '/^\s*11 /,/^\s*14 /p'
ケーシー

1
それは使用して短い手することができsed -n '/^11 /,/^14 /p' | awk '/NAME/{print $NF}' ますが、これを試してみましたか?
Rahul Patil

@RahulPatilはい、動作します。
Vinay 2014年

6

単語の境界を使用する:

grep '\bNAME1\b'

一致しませんか。NAME1NAME1XYZXYZNAME1

同様に、

sed -n '/11\b/,/14\b/p'

111およびを含む行とは一致しません142


編集:入力ファイルの番号は実際には行番号のようです。その場合は、次のように簡単に言うことができます。

sed '11,14!d'

目的の行を取得します。


一つだけありNAMEライン11と14では、なぜされて間sedを見て111とは114?それを間111から見ないようにする方法は114
Vinay

@VinayChalluru sed式を変更する方法については、上記の回答を参照してください。
devnull 2014

これは私の疑問に答えます。試してみて、お知らせします。
Vinay

単語の境界のために、grepとの-wフラグ?ですよね?
Rahul Patil

1
@RahulPatilうん、上の例で-wは同等です。以下のためsed例、-wわずかに異なっています。
devnull 2014

4

AWKを使用できます

awk 'NR>=13 && NR<=17 && /NAME/{print $NF}' infile

これは、13から17までの行を探し、次に名前を検索し、一致する場合は、 Name = LastWord


私はこれをしようとすると、私は、入力ラインの数が少ない199以上でなければならないというエラーを取得する
ビナイ

@VinayChalluruはコマンドで出力を表示できます。paste.ubuntu.comを使用してください
Rahul Patil

謝罪。$以前に追加したNRため、エラーが発生しました。
Vinay

@VinayChalluru大丈夫です。それはあなたが各ansを試したりテストしたりして新しいことを学ぶ良いことです。:D
Rahul Patil

丁度。まだまだ先です。:-)
Vinay

4

これにsedは他のツールは必要ありません。全体を簡単に処理できます。

sed -nr '/11/,/14/{s/^.*NAME =\s*(\S*).*$/\1/p}' <$infile

これにより、入力ファイルの11行目と14行目の間でそのフレーズが見つかったすべての行について、「NAME =」というフレーズに続く非空白文字の最初のシーケンスのみが提供されますsed


3

sedはこの仕事に適したツールではありません。awkを使用して、探しているIDを指定し、次に表示されるNAMEを出力します。

awk -v id="id2" '
    $NF == id {have_id = 1} 
    have_id && $0 ~ /NAME/ {print $NF; exit}
' filename

awkコマンドの2行目と3行目を説明できますか?
エリック、2014年

0

行番号ではなくID参照に基づく汎用バージョン

sed -n '1h;1!H;
$ {
  x
  s/.*/&\^J/
: clean
#  put your ID pattern here in place of id9
  s/.*\(id9 *\n.*\)id[0-9]\{1,\} *\n.*/\1/
  t clean
  s/.*NAME = \([^[:cntrl:]]*\)\n.*/\1/
  p
  }' YourFile
  1. ファイル全体をロードする
  2. IDグループの一部ではないクリーンセクション(再帰的)
  3. グループ内のNAMEのコンテンツ値を取得するだけです
  4. 結果を印刷する

0

次のようにsedを使用して、一致するパターンを含む行を印刷できます。

sed -n '/pattern/p'  Filename
  • -n-これらのオプションは、この自動印刷を無効にし、sedは、pコマンドを介して明示的に指示された場合にのみ出力を生成します。

  • p -印刷

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.