web-dev-qa-db-ja.com

sedコマンドを使用して、パターンが一致したかどうかを確認する条件を適用します

文字列::=BEGINを検索していますが、Wordが見つかったかどうかを確認する条件を適用したいです。

だから、私が意味するのは、これらの線に沿ったものです:

if (sed command does find a match for "::=BEGIN")
then i=1 
else i=0

また、1(yesが見つかった場合)と0(not found)を変数 "i"に入れる必要があります。

私を助けてください。ソリューションへの説明も提供してください!ありがとう!

7
SamFlynn

grepはその仕事を十分に果たします。

$ echo "::=BEGIN" > testfile1.txt

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND

$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND

このコードは、サブシェル内で単純な検索を実行するだけです。 &&または論理ANDオペランドは、最初のコマンドが成功したかどうかを確認し、成功した場合はecho "FOUND"を実行します。 ||は、そのエコーが実行されたかどうか、つまり何かが見つかったかどうかを確認します。 2番目のエコーは、最初のコマンドが失敗した場合にのみ実行されます。

awkバージョンは次のとおりです。

$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT

$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND

ここでの基本的な考え方は、iNOTFOUNDに設定し、文字列が見つかった場合はFOUNDITに変更することです。最初ののセットがファイルの処理を終了した後、最後にiを出力し、何かを見つけたかどうかを知らせます。

編集:コメントで、結果を変数に入れたいと述べました。シェルは、前のコマンドの終了ステータスを報告する変数$0をすでに提供しています。終了ステータス0は成功、それ以外はすべて-失敗を意味します。例えば、

$ grep "::=BEGIN" -q testfile1.txt  
$ echo $?
0

変数で終了ステータスを使用する場合は、MYVAR=$(echo $?)のように使用できます。覚えていますか、$?前のコマンドの終了ステータスを報告します。そのため、grepコマンドの直後にこれを使用する必要があります。

以前のawkとgrepのワンライナーを引き続き使用する場合は、同じトリックMYVAR=$()を使用して、中括弧の間に任意のコマンドを配置できます。出力は変数MYVARに割り当てられます。

6

GNU sed(Ubuntuシステムにデフォルトでインストールされる)を使用する場合

{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile

この答えに関するいくつかの事実:

  1. sedQuitsは、非常に最初の一致がファイル内のどこかで見つかるとすぐに入力します。つまり、無駄になりませんinfileの読み取りを続行します。

  2. sedreturnsそのexit code数値または1アドレスが見つからなかった/見つからなかったかどうかに応じて正規表現.

  3. $iは、終了時にsedの戻り値に設定されます。

  4. {グループ化; }は、起こりうるリダイレクトエラーを確実に処理するために使用されます。シェルがファイルをまったく開けない場合、$iは設定されないため、誤検知が回避されます。

これはおそらくgrep -qよりも優先されるべきではありません。基本的にalso上記のすべてを行うことができます(if逆に)、POSIXで実行し、通常は高速です。

すでに与えられたgrep -qの答えは非常に良いですが、少し簡潔です:

grep -q pattern ./infile; i=$((!$?))
5
mikeserv

これを使用できます:

#!/bin/bash
while IFS= read -r line; do
    case "$line" in *::=BEGIN*) i=1 && break;;         
                               *) i=0
    esac
done <file.txt

これは、ファイルをfile.txt行ごとに検索し、::=BEGINの一致が見つかった場合、変数i=1を設定して終了します。一致が見つからない場合、変数はi=0として設定されます。

4
heemayl

私のsedバージョン

sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'

変数iに格納するには:

i=$(sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}')

例:

$ echo "::=BEGIN" > foo
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1
$ echo "::=NOT_BEGIN" > foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
0
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1

説明:

  • ::=BEGINが見つかった場合、1を出力し、nextにジャンプします
  • ::=BEGINが見つからない場合は、0を印刷します
3
A.B.

sed(Stream EDitor)は、この種のことには適切なツールではありません。単にbashifステートメントを使用して、入力を正規表現に一致させることができます:

#!/bin/bash

#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
  • input="$(< inputfile)"inputfileの内容を変数$inputに割り当てます
  • [[ "$input" =~ ::=BEGIN ]] && i=1 || i=0:変数::=BEGINの内容に対して正規表現$inputと一致します。一致する場合は、1$iに割り当てます。それ以外の場合は、0$iに割り当てます
2
kos