sed 명령은 구성 파일의 값을 대체합니다.

sed 명령은 구성 파일의 값을 대체합니다.

자동화 스크립트를 작성 중인데 구성 파일의 값을 변경해야 합니다. 편집하려는 구성 파일에는 다음과 같은 줄이 있습니다(앞 공백 포함).

    "peer-port": 23456,

234565자리 숫자가 될 수 있습니다. 내가 작성 중인 스크립트에는 이라는 변수에 저장된 새 포트가 전달됩니다 $newport. sed(또는 awk) 명령을 사용하여 바꾸는 방법"23456", (또는 무엇이든) 새 포트 값은 변수에 포함됩니다 $newport.

비교적 완전한 것견본구성 파일은 다음과 같습니다.

{
    "alt-speed-down": 50, 
    "alt-speed-enabled": false, 
    "alt-speed-time-begin": 540, 
    "alt-speed-time-day": 127, 
    "alt-speed-time-enabled": false, 
    "alt-speed-time-end": 1020, 
    "alt-speed-up": 50, 
    "bind-address-ipv4": "0.0.0.0", 
    "bind-address-ipv6": "::", 
    "blocklist-enabled": false, 
    "blocklist-url": "http://www.example.com/blocklist", 
    "cache-size-mb": 2, 
    "dht-enabled": true, 
    "download-dir": "/var/media/orng/dl/", 
    "download-queue-enabled": true, 
    "download-queue-size": 1, 
    "encryption": 2, 
    "idle-seeding-limit": 30, 
    "idle-seeding-limit-enabled": false, 
    "incomplete-dir": "/var/media/orng/dl//incoming", 
    "incomplete-dir-enabled": true, 
    "lpd-enabled": false, 
    "message-level": 2, 
    "peer-congestion-algorithm": "", 
    "peer-limit-global": 100, 
    "peer-limit-per-torrent": 20, 
    "peer-port": 51413, 
    "peer-port-random-high": 65535, 
    "peer-port-random-low": 49152, 
    "peer-port-random-on-start": false, 
    "peer-socket-tos": "default", 
    "pex-enabled": true, 
    "port-forwarding-enabled": true, 
    "preallocation": 1, 
    "prefetch-enabled": 0, 
    "queue-stalled-enabled": true, 
    "queue-stalled-minutes": 30, 
    "ratio-limit": 0, 
    "ratio-limit-enabled": true, 
    "rename-partial-files": true, 
    "rpc-authentication-required": false, 
    "rpc-bind-address": "0.0.0.0", 
    "rpc-enabled": true, 
    "rpc-password": "{43041796ac49801e85577ba94a0e4ee5642d53a6soamZcAy", 
    "rpc-port": 9091, 
    "rpc-url": "/transmission/", 
    "rpc-username": "", 
    "rpc-whitelist": "127.0.0.1, 192.168.1.*", 
    "rpc-whitelist-enabled": true, 
    "scrape-paused-torrents-enabled": true, 
    "script-torrent-done-enabled": false, 
    "script-torrent-done-filename": "", 
    "seed-queue-enabled": false, 
    "seed-queue-size": 10, 
    "speed-limit-down": 100, 
    "speed-limit-down-enabled": false, 
    "speed-limit-up": 100, 
    "speed-limit-up-enabled": false, 
    "start-added-torrents": true, 
    "trash-original-torrent-files": false, 
    "umask": 18, 
    "upload-slots-per-torrent": 14, 
    "utp-enabled": true, 
    "watch-dir": "/var/media/orng/dl//watch", 
    "watch-dir-enabled": true
}

답변1

jq --argjson port "$newport" '."peer-port" |= $port' file.json >file-new.json

file-new.json그러면 키 peer-port값이 쉘 변수 값으로 변경된 새 파일이 생성됩니다 $newport. 쉘 변수는 있는 그대로, 즉 인코딩 없이 삽입되므로 순수한 정수인지 확인하십시오( 인코딩된 문자열로 삽입하는 --arg대신 사용).--argjson

답변2

다음 테스트를 시도해 보세요.

sed 's/^    "peer-port": [0-9]*,/    "peer-port": '"${newport}"',/' settings.json

...출력을 확인하고 괜찮아 보이면 -i다음과 같이 실제로 파일을 변경하기 위해 하나를 추가하세요.

sed -i 's/^    "peer-port": [0-9]*,/    "peer-port": '"${newport}"',/' settings.json

메모:s대리자문자열에 약간의 조정이 필요할 수 있습니다. (공백이 공백인지 탭인지에 따라 " "를 " ")로 바꿉니다.\t

보다 컴팩트하고 효율적인(하지만 이식성이 떨어지는) 접근 방식:

sed `/^    "peer-port": /{s/ [0-9]*,/ '"${newport}",'/;q}' settings.json

답변3

일반적으로 sed 검색 문자열에 대한 패턴을 생성하는 데 전체 문자열이 필요하지 않으며 고유한 부분만 필요하며 "(peer-port.+) ([0-9]+)"는 완벽하게 충분해 보입니다. 이 경우 작은 꼬리가 있는 키워드를 찾은 다음 일련의 숫자를 찾아 모든 것을 변경되지 않은 첫 번째 항목(\1)으로 바꾸고 두 번째 항목을 스크립트의 문자열로 바꿉니다.

#!/bin/bash

FNAME=$1
NPORT=$2
SSTR='{s/(peer-port.+) ([0-9]+)/\1 '$NPORT'/};'
echo "new port $NPORT in $FNAME"

sed -E -i -e "$SSTR" $FNAME

답변4

중첩된 데이터 형식(예: json)을 구문 분석하려면 해당(json 형식 인식) 유틸리티를 사용하여 수행해야 합니다. sed나만 아는 라인이다. 다음은 walk-path unix 유틸리티를 기반으로 한 간단한 솔루션입니다.jtc:

bash $ newport=12345
bash $ jtc -w[peer-port] -u"$newport" -f file.json 
bash $ jtc -w[peer-port] file.json 
12345
bash $ 

관련 정보