이 프로젝트에는 작곡가.json을 사용하는 수백 개의 애플리케이션이 있습니다. 저는 Bash 스크립트를 사용하여 새 버전을 받는 응용 프로그램이 포함된 파일의 버전 번호를 확인하고 업데이트하고 있습니다.
예를 들어 원본 파일은 다음과 같습니다(해당 부분만 넣었습니다).
{
"name" : "test/graylogger"
"version" : "1.1.1"
...
"require": {
"test/phpunit": "4.8.23"
}
다음과 같이 업데이트하고 싶습니다.
{
"name" : "test/graylogger"
"version" : "1.1.2"
...
"require": {
"test/phpunit": "4.8.24"
}
그러나 결과는 다음과 같습니다(내가 원하지 않음).
{
"name" : "1.1.2"
"version" : "1.1.2"
...
"require": {
"test/phpunit": "4.8.24"
}
기본적으로 내 스크립트는 "버전"을 검색하고 그 뒤의 두 번째 인용문을 하나씩 업데이트한 다음 폴더 파일 이름(이 경우 "graylogger")을 기준으로 반복한 다음 응용 프로그램 폴더가 포함된 다른 항목을 기준으로 반복합니다. 그러나 어떤 이유에서인지 이름도 업데이트되는데, 이는 내가 원하지 않습니다. 이 작업을 수행하는 데 사용하는 코드 조각은 다음과 같습니다.
while read line2; do
line1="$line1\"" #I did this to prevent any repetitive names from upping twice
original=$(grep -hr "$line1" /Websites/"$line2"/composer.json | awk -F \" '{print $4}')
if [["$original" != *"$line1"*]]; then
sed -i'' s,"$original","$version",g composer.json
done < websites.txt
line1
파일에서 업데이트되는 애플리케이션입니다.
line2
업데이트되는 파일입니다.
두 번째 텍스트의 텍스트에 앱 이름이 포함되어 있고 업데이트되지 않는 경우 변경 사항을 제외하는 if 문을 만들어 보았지만 작동하지 않는 것 같습니다.
이 작업은 Mac에서 수행됩니다.
감사해요!
답변1
jq
명령줄에서 JSON을 처리하기 위한 도구입니다., 기본 텍스트 수정보다 구조화된 데이터를 처리하는 데 더 적합합니다. 다음은 실제로 수행하려는 작업과 일치하는 것으로 보이는 일부 jq입니다.
program=test/graylogger
version=1.1.2
jq --arg prog "$program" --arg version "$version" '
(.. | select(.name? == $prog).version) = $version
| (.. | select(has($prog)?)[$prog]) = $version' composer.json | sponge composer.json
jq 프로그램 자체는 작은따옴표로 묶인 두 줄로 구성됩니다.
그것은 대체할 것이다둘 다"이름이 지정된" test/graylogger 개체의 "version" 속성(두 번째 줄은 test/graylogger jq jq
프로그램 으로 시작합니다 |` 첫 번째 줄은 이를 구분하므로 하나만 있는 경우 제거할 수 있습니다.) and the
property of any object that has one (the second line of the
program) with the new version. You can edit to only one or the other as appropriate - the pipe
첫 번째 줄은 다음을 사용하여 적합한 개체를 찾는 방식으로 작동합니다 ..|select(.name? == $prog)
.모든값( )을 입력하고 우리가 찾고 있는 객체( 가 전혀 없음 ) ..
만 계속 살펴본 다음 해당 객체에 버전 속성( )을 설정합니다 .name
name
.version = $version
has
두 번째 줄도 마찬가지로 키가 프로그램 이름과 일치하는 개체를 선택한 다음 []
인덱스를 사용하여 해당 속성을 업데이트합니다.
나는 사용했다sponge
moreutils에서sed -i
파일 덮어쓰기 동작을 제자리에 복사합니다 . 대신 임시 파일을 사용할 수 있습니다. 이들 모두는 기존 루프 구조에 입력되어 모든 파일에 적용될 수 있습니다.