sed 与 awk:逐行读取文件并附加到另一个文件中的特定行

sed 与 awk:逐行读取文件并附加到另一个文件中的特定行

考虑下面的两个文件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/要读取docker-compose.txtYAML 文件,请在文档结构中找到正确数组的正确部分,并将其替换为从文件中读取的数据users.txt

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

这将禁用所有输入的默认读取,而是使用表达式中的-n第一条指令读取第一个输入文件。读取后,将迭代该数组,查找以 text 开头的任何文本元素。一旦找到,它将被替换为字符串,后跟第二个输入文件中找到的内容。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

-y选择YAML 输出的选项yq。如果没有它,您将获得 JSON 输出(以及-tTOML 和-xXML)。

答案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:

相关内容