awkでsed:ファイルを1行ずつ読み、別のファイルの特定の行に追加する

awkでsed:ファイルを1行ずつ読み、別のファイルの特定の行に追加する

次の2つのファイルを検討してくださいusers.txt

Arnold.Bosch
David.Ledru
Mehri.Sunny

そしてdocker-compose.txt

version: '3.9'
services:
  strongswan-server:
    image: vpn-strongswan
    container_name: strongswan-server

    networks:
      strongswan-server:
    environment:
      - STRONGSWAN_CLIENTS=
    sysctls:
    volumes:
    ports:
      - 500:500/udp
      - 4500:4500/udp
volumes:
  strongswan-server-conf:
networks:
  strongswan-server:

次のスクリプトは、sedフィルタを使用してSTRONGSWAN_CLIENTS

#!/bin/bash
while IFS= read -r line; do
    echo "Text read from file: $line"
  
    sed -i "10s/$/ $line/" $2

done < "$1" 

environment:
  - STRONGSWAN_CLIENTS=Arnold.Bosch David.Ledru Mehri.Sunny

これを達成する別の方法があるかどうか疑問に思いますawk

答え1

STRONGSWAN_CLIENTS行の末尾に追加されるコードの機能と、実行したいことを行う方法は次のとおりです。

$ awk 'NR==FNR{users=users OFS $0; next} /STRONGSWAN_CLIENTS=/{$0=$0 users} 1' users.txt docker-compose.txt
version: '3.9'
services:
  strongswan-server:
    image: vpn-strongswan
    container_name: strongswan-server

    networks:
      strongswan-server:
    environment:
      - STRONGSWAN_CLIENTS=users Arnold.Bosch David.Ledru Mehri.Sunny
    sysctls:
    volumes:
    ports:
      - 500:500/udp
      - 4500:4500/udp
volumes:
  strongswan-server-conf:
networks:
  strongswan-server:

答え2

次のjqラッパーを使用してください。yqhttps://kislyuk.github.io/yq/YAMLファイルを読み取るには、docker-compose.txtドキュメント構造内の正しい配列の正しい部分を見つけて、ファイルから読み取ったデータで置き換えますusers.txt

yq -y -n '
    input | (
        .services."strongswan-server".environment[] | 
        select(startswith("STRONGSWAN_CLIENTS="))
    ) = "STRONGSWAN_CLIENTS=" + input' docker-compose.txt users.txt

これにより、すべての入力のデフォルトの読み込みが無効になり、代わりに式-nの最初の命令を使用して最初の入力ファイルを読み込みます。読み取られた後、配列は、テキストで始まるテキスト要素を見つけるために繰り返されます。見つかったら、2番目の入力ファイルで見つかった内容は、後続の文字列に置き換えられます。inputjqenvironmentSTRONGSWAN_CLIENTS=STRONGSWAN_CLIENTS=

質問のデータに関する結果を提供します。

version: '3.9'
services:
  strongswan-server:
    image: vpn-strongswan
    container_name: strongswan-server
    networks:
      strongswan-server: null
    environment:
      - STRONGSWAN_CLIENTS=Arnold.Bosch David.Ledru Mehri.Sunny
    sysctls: null
    volumes: null
    ports:
      - 500:500/udp
      - 4500:4500/udp
volumes:
  strongswan-server-conf: null
networks:
  strongswan-server: null

短いバリエーション、常に設定最初配列要素environment:

yq -y -n 'input | .services."strongswan-server".environment[0] = "STRONGSWAN_CLIENTS=" + input'  docker-compose.txt users.txt

-yYAML出力オプションを選択しますyq。これがなければ、JSON出力(-tTOMLとXMLを含む-x)を取得します。

答え3

使用sedtr

$ sed "s/- STRONGSWAN_CLIENTS=/&$(tr '\n' ' ' < users.txt)/" docker-compose.txt
version: '3.9'
services:
  strongswan-server:
    image: vpn-strongswan
    container_name: strongswan-server

    networks:
      strongswan-server:
    environment:
      - STRONGSWAN_CLIENTS=Arnold.Bosch David.Ledru Mehri.Sunny 
    sysctls:
    volumes:
    ports:
      - 500:500/udp
      - 4500:4500/udp
volumes:
  strongswan-server-conf:
networks:
  strongswan-server:

答え4

STEP1:

rep=$(perl -pne "s/\n/ /g" f1)

STEP2:

sed -i "/STRONGSWAN_CLIENTS=/s/.*/&$rep/g" f2

出力

version: '3.9'
services:
  strongswan-server:
    image: vpn-strongswan
    container_name: strongswan-server

    networks:
      strongswan-server:
    environment:
      - STRONGSWAN_CLIENTS=Arnold.Bosch David.Ledru Mehri.Sunny 
    sysctls:
    volumes:
    ports:
      - 500:500/udp
      - 4500:4500/udp
volumes:
  strongswan-server-conf:
networks:
  strongswan-server:

関連情報