
特定のファイルで特定のパターンを見つけて置き換える必要がありますが、パターンが見つからない場合は1または他の値を返す必要があります。
sedだけを使用してこれを実行できますか?または、パターンが存在することを確認するために別のコマンドを使用する必要がありますか?
どんな提案がありますか?
答え1
この回答を確認してください。sed
ファイルが変更されたかどうかを確認する方法。
リクエストした内容とほぼ同じです。awk
他のファイルとdiff
2つのファイルを使用または出力することをお勧めします。
答え2
Sed は各パターン空間のコマンドを順次処理します。良いパターンを取得するためにアドレス指定を使用している場合は、q
sedのコマンドを使用して正の値を返すことができます。
sed '/if-the-pattern-space-has-this/<do this command>' <file>
コマンドが終了した後(この場合は区切り;
)、次のコマンドが実行されます(前のパターンを見つけて終了しなかった場合)。
最後のコマンドは$q 1
sed アドレスを使用し、ドル記号はコマンドがファイルの最後の行でのみ実行されることを示します。ファイルの最後の行ですでに良いパターンが見つかった場合は、すでに終了しているので、最後の手段としてのみ使用してください。もしそうなら、あなたは否定的なパターンに戻ります。
> sed -n '/good-pattern/q 0;$q 1' <<< "bad-pattern"
> echo $?
1
> sed -n '/good-pattern/q 0;$q 1' <<< "good-pattern"
> echo $?
0
これは、ファイル領域内でパターンマッチングを見つけるためにアドレス指定を使用する場合に便利です。これはgrep
簡単に表現するのが難しいです(公平に言えば、sed
少し踊らなければできません)。
^block:
この例では、空行で始まり終わるファイル部分を探し、crazy
そのブロック内で単語が見つかった場合はtrueを返します。
sed -n '/^block:/,/^$/{/crazy/q 0};$q 1' <<END && echo -e "\n--------------\n FOUND" || echo "\n----------------\n NOT FOUND"
this thing
block:
is crazy
END
--------------
FOUND
^block:
この例では、to の範囲外に「crazy」という単語がリストされているため、<empty line>
false を返します。
> sed -n '/^block:/,/^$/{/crazy/q 0};$q 1' <<END && echo -e "\n--------------\n FOUND" || echo -e "\n----------------\n NOT FOUND"
this thing
block:
is crazy
END
----------------
NOT FOUND
一部の変更が適用されたかどうかに応じて正または負を返すには、次のようにすることをお勧めします。
.sed ファイル:substitutions.sed
# Searching for the word "crayons", replace this
# with "pizza" to see a positive match. The replacement
# word is "meanies", which you can also replace.
s/crayons/meanies/
# We print each line regardless of a pattern match
p
# If the most recent 's' command did a substitution, take
# the branch to the loop.
t loop
# If we're not on the last line, delete the pattern space and
# start processing the next line.
$!d
# This only happens on the last line. If we get here, swap the
# last hold space in and then return positive or negative based
# on the content in the hold space. The hold space should only
# have matching content if we matched once before and swapped
# the matching pattern into the hold space.
x
/meanies/q 0
# If we don't match the replacement pattern then return falsy.
q 1
# This loop is only taken on a positive match, effectively
# just swapping the most recent match into the hold space.
:loop
x
データファイル:data.txt
file has some
content, be kind pizza
don't eat pizza after 8
because of the pepperoni monsters
sed コマンド:
sed -nf substitutions.sed data.txt && echo -e '\nGood' || echo -e '\nBad'
sedコマンドは、-n
sedスクリプトの最後に到達するたびにパターンスペースが印刷されないことを示すために使用されます。 -f
次のファイルから sed コマンドを読み取ったことを示します。
クレイジーをしたい場合は、sedをインタプリタとしてシェルスクリプトにラップできます(discover its locationを使用which sed
)。簡潔にするために、今回はコメントを省略し、代替パターンを「クレヨン」を「ピザ」に変更しました。
シェルスクリプト:sed.sh
#!/usr/bin/sed -nf
s/pizza/meanies/
p
t loop
$!d
x
/meanies/q 0
q 1
:loop
x
移動する:
> ./sed.sh data.txt
file has some
content, be kind meanies
don't eat meanies after 8
because of the pepperoni monsters
> echo $?
0