Bash의 여러 sed 명령

Bash의 여러 sed 명령

프로세스로 변환하려는 JSON 형식의 파일 사용자 이름과 비밀번호가 있습니다.

나는 sed그것을 처리하기 위해 다른 명령을 사용했지만 내가 알고 싶은 것은 미래에 세 명령을 모두 하나로 묶는 방법입니다.

원본 형식

    { "user.name1" : "hashed_password",
"user.name2" : "hashed_password" }

원하는 출력

user.name:hashed_password

이것은 내가 실행한 명령이지만 파이핑을 사용하거나 단순히 연결하여 오류가 발생하는 명령을 함께 연결할 수 없었습니다 sed: -e expression #1, char 8: unknown option to 's'.

위반 명령 ...

sed -i 's/\"//g/s/\,/\n/g/\s//g' input_file 
sed: -e expression #1, char 8: unknown option to `s'

아래 명령을 어떻게 하나로 연결할 수 있습니까?

명령 큰따옴표 제거

sed -i 's/\"//g' input_file

쉼표를 새 줄로 바꾸세요.

sed -i 's/\,/\n/g' input_file

공백 제거

sed -i 's/\s//g input_file

답변1

여러 sed명령을 하나의 "스크립트", 여러 플래그를 사용할 수 있습니다 -e(이식 가능).

sed -i -e 's/\"//g' -e 's/\,/\n/g' -e 's/\s//g' input_file

또는 세미콜론 구분 기호(일부 구현에서는 사용할 수 없음):

sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file

중괄호에 대한 처리도 추가해야 합니다 {}.


JSON을 올바르게 구문 분석하고 처리하려면 실제로 사용해서는 안 됩니다 sed.jq!

jq -r 'keys[] as $k | "\($k):\(.[$k])"' input_file

산출:

user.name1:hashed_password
user.name2:hashed_password
  • keys[] as $k값을 저장하는 각 키를 반복합니다.$k
    • 즉: user.name1,user.name2
  • "\($k):\(.[$k])"$k및를 대체하여 문자열을 형성합니다..[$k]
  • 을 사용하면 -r출력 문자열에서 따옴표가 제거됩니다(날것의방법)

를 사용하여 sedJSON을 처리하면 모든 종류의 문제가 발생하게 됩니다. 예를 들어 다음(완전히 유효한 JSON) 입력을 어떻게 처리하시겠습니까?

{
    "user.name1" :
        "hashed_password",
    "user.name2" :
        "hashed_password"
}

답변2

JSON과 같은 표준화된 입력을 처리할 때는 일반적으로 정규식보다는 적절한 파서를 사용하는 것이 더 좋습니다. 예를 들어, 모든 이스케이프 시퀀스를 올바르게 변환합니다(특정 입력 데이터에서는 불가능할 수도 있음).

안타깝게도 coreutils에는 JSON을 처리할 수 있는 훌륭한 도구가 없습니다.애티가 제공한 jq패키지를 자유롭게 설치할 수 있다면 괜찮은 옵션입니다.

추가 패키지를 설치할 수 없는 경우 Python에서는 특별히 어렵지 않습니다. 예를 들어 다음 스크립트를 사용하십시오.

import json,sys
for (k, v) in json.load(sys.stdin):
    print(k + ":" + v)

한 줄로 압축할 수 있습니다.

cat inputdata | python -c 'import json,sys;print("\n".join((k + ":" + v) for (k, v) in json.load(sys.stdin).items()))'

답변3

이 명령에서 수행하는 간단한 문자 삭제의 경우 sed대신 를 사용하는 것이 좋습니다. 이 명령의 tr유일한 목적은 줄 바꿈을 포함한 개별 문자를 삭제, 압착 또는 교체하는 것입니다( sed일반적으로 줄 바꿈을 버퍼 구분 기호로 사용하는 정규 표현식을 기반으로 함). 따라서 sed를 사용하여 개행 문자를 수정하는 것은 까다롭습니다.) 나는 이 tr명령이 당신이 찾고 있는 모든 것을 수행한다고 생각합니다.

cat json_filename | tr -d "{}\" \012\011\015" | tr "," "\012"

첫 번째 tr명령은 모든 중괄호, 큰따옴표, 공백, 캐리지 리턴(8진수 012, ascii 10), 탭(8진수 011, ascii 9 및 줄바꿈(8진수 015, ascii 13) 문자를 삭제합니다. 두 번째 tr명령은 모든 쉼표를 다음으로 바꿉니다. 캐리지 리턴. JSON 파일의 변수 이름과 값에 쉼표가 포함되지 않는 한 이러한 명령을 사용하면 전용 JSON 파서가 필요하지 않습니다.

즉, 각각 독립적으로 작동하는 명령 세트가 있는 경우 "-f" 옵션을 사용하여 파일에서 개별 명령을 읽는 것이 sed가장 쉽게 결합될 수 있습니다 . seds/.../.../g 문자열을 파일에 넣고 각 문자열을 한 줄에 입력한 다음 "-f" 옵션 뒤에 해당 파일 이름을 지정하면 됩니다. 예를 들어, sed나열한 세 가지 명령이 만족스러우면 다음 내용이 포함된 "json.convert.sed"라는 파일에 해당 명령을 넣을 수 있습니다.

s/\"//g 
s/\,/\n/g
s/\s//g

sed그런 다음 다음을 사용하여 이 명령 파일을 호출합니다 .

sed -f json.convert.sed

즉, 이러한 sed명령은 귀하가 원하는 것을 달성하는 데 작동하지 않으며 귀하가 sed개행 문자를 수정할 수 있는지 확신할 수 없습니다. 이는 sed한 번에 한 줄씩 편집하도록 설계된 이전 "ed" 줄 편집기("스크립트" 가능 버전)를 기반으로 하기 때문입니다. 따라서 각 입력 줄은 줄 바꿈을 구분 기호로 사용하여 "분석"됩니다. 개행 없이 행이 편집 엔진에 전달되고, 편집 명령이 적용된 다음, 편집된 행이 개행과 함께 출력됩니다. 그런 다음 루프가 반복됩니다. 나는 sed먼저 tr. tr에서 줄 바꿈을 삭제하기만 하면 이 방법을 사용할 필요가 없습니다 tr. 그러나 예를 들어 개행 문자를 후행 공백이 있는 세미콜론으로 변환하려는 경우 다음과 같은 방법이 있습니다.

cat input_file | tr "\012" "%" | sed "s/%/; /g"

(개행은 에 의해 %로 변환된 tr다음 sed모든 % 문자를 "; " 문자 쌍으로 변환합니다.)

답변4

다음과 같이 결합할 수 있습니다.

sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file

의 제거를 추가하는 것을 잊었습니다 {}. 따라서 아마도 다음을 원할 것입니다.

sed -i 's/\"//g;s/\,/\n/g;s/\s//g;s/{//g;s/}//g' input_file

관련 정보