Bash에서 대문자에 문자열을 추가하는 방법

Bash에서 대문자에 문자열을 추가하는 방법

다음은 몇 가지 샘플 코드입니다.

{"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

-CUTF-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 문서의 다른 위치에 저장된 경우 관련 요소가 추출되도록 표현식 .[]의 첫 번째 문자 만 변경하면 됩니다( 가 포함된 마지막 예제 표현식에는 분명히 다른 변경이 필요함).jqmap()

답변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"}

관련 정보