以下のような入力ファイル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
「スイッチ」はありますか、それとも何か不足していますか?
検索したい行番号がわかっている場合は(Qが示唆しているように)、不要な行と一致しないように正規表現を厳しくします。
たとえば、次のように変更します。
sed -n '/11/,/14/p' | grep NAME | awk -F "= " '{print $2}'
に
sed -n '/^11 /,/^14 /p' | grep NAME | awk -F "= " '{print $2}'
^
は、特定の行番号が確実に一致することを保証する番号の後の行とスペースに一致し、不要なブロックを処理しません。
単語境界を使用する:
grep '\bNAME1\b'
NAME1
と一致し、NAME1XYZ
またはXYZNAME1
とは一致しません。
同様に、
sed -n '/11\b/,/14\b/p'
111
および142
を含む行とは一致しません。
編集:入力ファイルの番号は実際には行番号のようです。その場合は、次のように簡単に言うことができます。
sed '11,14!d'
目的の行を取得します。
これには他のツールは必要ありません。sed
で簡単に全体を処理できます。
sed -nr '/11/,/14/{s/^.*NAME =\s*(\S*).*$/\1/p}' <$infile
これにより、入力ファイルsed
の11行目から14行目までの間にフレーズが見つかるすべての行について、「NAME =」というフレーズに続く非空白文字の最初のシーケンスのみが提供されます。
AWKを使用できます
awk 'NR>=13 && NR<=17 && /NAME/{print $NF}' infile
これは、13から17までの行を検索し、名前を検索します。一致する場合、Name = LastWord
から最後の単語を出力します
sedはこの仕事に適したツールではありません。 awkを使用して、探しているIDを指定し、次に表示されるNAMEを出力します。
awk -v id="id2" '
$NF == id {have_id = 1}
have_id && $0 ~ /NAME/ {print $NF; exit}
' filename
行番号ではなく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
次のようにsedを使用して、一致するパターンを含む行を印刷できます。
sed -n '/pattern/p' Filename
-n
-これらのオプションはこの自動印刷を無効にし、sedはp
コマンドで明示的に指示された場合にのみ出力を生成します。
p
-印刷