![Bash에서 대문자에 문자열을 추가하는 방법](https://linux55.com/image/203165/Bash%EC%97%90%EC%84%9C%20%EB%8C%80%EB%AC%B8%EC%9E%90%EC%97%90%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%20%EC%B6%94%EA%B0%80%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
다음은 몇 가지 샘플 코드입니다.
{"key_code":"a"},
{"key_code":"B"},
{"key_code":"c"},
{"key_code":"D"}
이것이 내가 하고 싶은 일이다:
{"key_code":"a"},
{"key_code":"b","modifiers":"left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers":"left_shift"}
내 IDE에서는 대소문자를 구분하여 검색 "([A-Z])"
하고 다음으로 바꿀 수 있지만 "\L$1", "modifiers": "left_shift"
bash 스크립트에서는 사용할 수 없는 것 같습니다.
\L
저는 Mac OS X를 사용하고 있어서 이것이 문제를 일으키는 것 같습니다 .
나는 여러 버전을 시도했습니다:
sed -i "" 's/"([A-Z])"/"\L$1","modifiers": "left_shift"/g' file
그리고
sed -i "" "s/\"([A-Z])\"/\"\L$1\",\"modifiers\": \"left_shift\"/g" file
하지만 행운은 없습니다. 이리저리 돌아다니려고 노력했지만 awk
알 수 없는 것 같습니다...
답변1
Macos에서 발견된 FreeBSD는 대체 AFAIK를 sed
지원하지 않습니다 \L
. 언제든지 다음을 사용할 수 있습니다 perl
.
perl -pi -e 's/"\p{Lu}"/\L$&,"modifiers":"left_shift"/g' file
-C
UTF-8로 인코딩된 비ASCII 대문자(예 Ê
: Ç
, Ξ
등) 도 처리하는 옵션이 추가되었습니다 .
답변2
표시하는 JSON 객체가 아래와 같이 최상위 배열의 일부라고 가정합니다(키와 값 외부의 공백 문자는 관련이 없습니다).
[
{
"key_code": "a"
},
{
"key_code": "B"
},
{
"key_code": "c"
},
{
"key_code": "D"
}
]
그런 다음 각 값이 대문자인지 테스트하고 key_code
대문자인 경우 modifiers
개체에 추가할 수 있습니다.
jq '(.[] | select(.key_code | test("[[:upper:]]"))) += { "modifiers": "left_shift" }' file
또는 (그러나 약간 더 짧음),
jq '(.[] | select(.key_code | test("[[:upper:]]"))).modifiers |= "left_shift"' file
map()
또는 최상위 배열에서 사용합니다.
jq 'map(select(.key_code | test("[[:upper:]]")).modifiers |= "left_shift")' file
질문에 주어진 입력을 기반으로 다음과 같은 출력이 생성됩니다.
[
{
"key_code": "a"
},
{
"key_code": "B",
"modifiers": "left_shift"
},
{
"key_code": "c"
},
{
"key_code": "D",
"modifiers": "left_shift"
}
]
배열이 더 큰 JSON 문서의 다른 위치에 저장된 경우 관련 요소가 추출되도록 표현식 .[]
의 첫 번째 문자 만 변경하면 됩니다( 가 포함된 마지막 예제 표현식에는 분명히 다른 변경이 필요함).jq
map()
답변3
입력이 매번 정확히 동일해 보인다면 이것으로 충분합니다.
awk '{if(/:"[A-Z]"/) sub(/"}/, "\",\"modifiers\":\"left_shift\"}"); print tolower($0) }' inputfile > outputfile
또 다른 옵션은 다음과 같습니다.
sed 's/"[A-Z]"/&,"modifiers": "left_shift"/g' inputfile | tr '[[:upper:]]' '[[:lower:]]' > outputfile
Mac에서는 테스트할 수 없지만 작동할 만큼 충분히 일반적인 것 같습니다.
tolower($0)
그리고 명령은 tr
모두 모든 것을 소문자로 반환하므로 바람직할 수도 있고 그렇지 않을 수도 있으므로 그다지 유연한 옵션은 아닙니다.
답변4
GNU sed 사용(아직 없는 경우 Mac에 설치):
$ sed 's/"[A-Z]"/\L&,"modifiers":"left_shift"/' file
{"key_code":"a"},
{"key_code":"b","modifiers":"left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers":"left_shift"}
\1
대신 역참조를 사용하고 대괄호를 이스케이프하여 리터럴이 아닌 그룹 경계를 캡처하는 경우 $1
기존 코드는 GNU sed에서도 작동합니다. 예:
$ sed 's/"\([A-Z]\)"/"\L\1","modifiers": "left_shift"/g' file
{"key_code":"a"},
{"key_code":"b","modifiers": "left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers": "left_shift"}
또는 기본 BRE 대신 ERE를 활성화합니다.
$ sed -E 's/"([A-Z])"/"\L\1","modifiers": "left_shift"/g' file
{"key_code":"a"},
{"key_code":"b","modifiers": "left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers": "left_shift"}