sedを使用して引用符内の文字列を置き換える方法

sedを使用して引用符内の文字列を置き換える方法

以下のコードで現在の時刻を変更するためにsedを使用したいと思います。

time0=$(date '+%Y-%m-%d')
time1=$(date '+%H:%M:%S')

time=$(echo ""$time0"T"$time1"Z")

最初の行で$ timeを置き換える

{
    "X-Apple-I-Client-Time" = "2020-07-08T12:55:08Z";
    "X-Apple-I-Locale" = "en_US";
    "X-Apple-I-MD" = "AAAABQAAABDBy+H0j9QAnYGIzrmKeh9DAAAAAw==";
    "X-Apple-I-MD-M" = "6Q3cWbCm2lI9rrTIyrAsku5zxqO/ZAv9HsW5kHo2thiPqFINp0/OsOz++KS/2vc0ImbI2iMVUbYCZjnS";
    "X-Apple-I-MD-RINFO" = 50660608;
    "X-Apple-I-TimeZone" = "GMT+7";
}

みんなありがとう

答え1

now=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
sed 's/\("X-Apple-I-Client-Time" = \).*/\1"'"$now"'";/' file

これにより、現在のUTCタイムスタンプが計算され、シェル変数に保存されますnow。次に、名前付きファイル内のfile正確な文字列を含む行を見つけ、"X-Apple-I-Client-Time" =その後のすべての項目をタイムスタンプと引用符で囲んだものに置き換えます;

結果は標準出力に書き込まれます。元のファイルを直接変更したい場合は、以下を使用してください。

now=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
cp file file.tmp &&
sed 's/\("X-Apple-I-Client-Time" = \).*/\1"'"$now"'";/' file.tmp >file &&
rm -f file.tmp

(これは壊れるでしょうfile.tmp

システム実装に「現在の場所」編集機能がsedある場合はそれを使用できます。バックアップファイルなしで編集するためにFreeBSDとmacOSで空の引数が必要では-iありません(参照:sed -i-ised -i(所定の位置で編集)を使用して移植性を達成するには?)。

答え2

  1. フォーマットされた日付の末尾にZ表示されるタイムゾーンはUTC(別名+0000)なので。date --utc代わりにそれを使用する必要がありますdate

    このファイルのすべてのエントリはX-Apple-I-Client-TimeUTCでなければなりません。実際のタイムゾーンはX-Apple-I-TimeZone

  2. なぜ使用する必要があり、$time0いつ$time11dateつのフォーマット文字列でフルタイムを生成できますか? (たとえば+%FT%TZ、%Fと%TがGNU拡張であるかどうか覚えていないため、dateこれを使用する必要があるかもしれません'+%Y-%m-%dT%H:%M:%SZ'。)

  3. 別の変数が必要な場合は、$time0コマンド$time1置換とエコーを使用してそれらを組み合わせることは$time不要ですが、おそらく最悪のアプローチです。次のように使用してください。

    time="${time0}T${time1}Z"
    
  4. タイムスタンプをファイルに挿入するには、次のようにします。

    time=$(date --utc +%FT%TZ)   # or maybe use '+%Y-%m-%dT%H:%M:%SZ' instead
    sed -i -e '/X-Apple-I-Client-Time/s/ = "[^"]*"/ = "'"$time"'"/' filename.txt
    

    または(必要に応じてスクリプトの他の場所で)$time0$time1

    time0=$(date --utc '+%Y-%m-%d')
    time1=$(date --utc '+%H:%M:%S')
    
    time="${time0}T${time1}Z"
    
    sed -i -e '/X-Apple-I-Client-Time/s/ = "[^"]*"/ = "'"$time"'"/' filename.txt
    
  5. 個人的$timeに名前が付けられた変数はtime組み込みコマンドと/usr/bin/time。誤って割り当ての=前にスペースを追加しました(例:time = "${time0}T${time1}Z" instead oftime = "$ {time0} T $ {time1} Z" ) will run thetime`コマンド)。

    $tワンタイム変数であるか、より説明的で少し長い変数であれば、おそらく使用します。

関連情報