行全体を変更する代わりに、sedを使用して特定の単語の後のテキストをどのように置き換えることができますか?

行全体を変更する代わりに、sedを使用して特定の単語の後のテキストをどのように置き換えることができますか?

特定の単語の後のテキストを変更しようとしていますが、行sed全体が変わっています。特定の単語の後の単語の抽出

入力ファイル:サンプル.txt

My Hostname:internal is valid.
some log file entries
some log file entries

出力:

My Hostname:mmphate
some log file entries
some log file entries

予想出力:

My Hostname:mmphate is valid.
some log file entries
some log file entries

Hostname:1つの単語だけを変更したい場合は、すべての単語を変更する次のスクリプトを作成しました。Hostname:

#!/usr/bin/env bash

HOST=$(curl -s 169.254.169.254/latest/meta-data/local-hostname)
while getopts ih opt
do
  case $opt in
  i)
    ;;
  h)
    sed -e "s/Hostname:.*/Hostname:$HOST/g" sample.txt
    echo "Updated Hostname: $HOST"
    ;;
  esac
done

ベストアンサー1

右回転入力は特別にエラーを引き起こす可能性があり、悪い場合はエラーはありませんが、まったく予期しない結果が生じる可能性があるため、s///入力を適切にエスケープするように注意する必要があります。sedたとえば、$HOSTアンパサンドまたはを含めると&どうなるか考えてみましょう/

# definitions
TAB=`echo 'x' | tr 'x' '\011'`; # tab
SPC=`echo 'x' | tr 'x' '\040'`; # space
eval "`echo 'n=qsq' | tr 'qs' '\047\012'`"; # newline

# construct regexes
s="[$SPC$TAB]";  # spc/tab regex
S="[^$SPC$TAB]"; # nonwhitespace regex

# perform the escape operation
esc() {
   set -- "${1//\\/\\\\}" # escape backslash to prevent it from dissolving
   set -- "${1//\//\\\/}" # escape forward slash to prevent from clashing with delimiters
   set -- "${1//&/\\&}"   # escape ampersand since it has a specific meaning rhs of s//
   set -- "${1//\"/\\\"}" # escape double quotes in an interpolation
   set -- "${1//$n/\\$n}" # escape newlines
   printf '%s\n' "$@"
}

# grab the hostname
HOST=$(curl -s 169.254.169.254/latest/meta-data/local-hostname)

# escape hostname to enable it to be used seamlessly on the rhs of s///
host_esc=$(esc "$HOST")

# and then...
sed -e "s/\(${s}Hostname\):$S$S*/\1:$host_esc/g" sample.txt

おすすめ記事