자동화 스크립트를 작성 중인데 구성 파일의 값을 변경해야 합니다. 편집하려는 구성 파일에는 다음과 같은 줄이 있습니다(앞 공백 포함).
"peer-port": 23456,
23456
5자리 숫자가 될 수 있습니다. 내가 작성 중인 스크립트에는 이라는 변수에 저장된 새 포트가 전달됩니다 $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 $