내부 따옴표를 필터링하는 방법은 무엇입니까? [폐쇄]

내부 따옴표를 필터링하는 방법은 무엇입니까? [폐쇄]

필터링이 가능합니까? 즉, 내부 따옴표 앞에 ESC를 넣는 것이 가능합니까?sed,아니면 다른 *NIX 도구(perl/python 제외)?

예(수정됨):

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | magic-filter
label="123 \"456\" 789\" \"AB C" e f gh

tag="123\"456\"789""AB C"

즉, 첫 번째와 마지막을 기준으로 필터링하는 필터가 필요합니다."char은 있는 그대로 전달되지만 다른 모든 항목은"로 대체됩니다\이어서".

답변1

GNU sed, 지원특정 개수의 모든 항목 바꾸기

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    sed -E 's/"/\\"/2g; s/\\("[^"]*)$/\1/'
label="123 \"456\" 789\" \"AB C" e f gh

모두 "(첫 번째 제외 ")는 로 교체된 \"다음 \마지막에서 제거됩니다.\"


GNU sed사용할 수 없는 경우 \첫 번째 항목에서도 제거하세요.\"

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    sed -E 's/"/\\"/g; s/\\"/"/; s/\\("[^"]*)$/\1/'
label="123 \"456\" 789\" \"AB C" e f gh

참고: 일부 버전에서는 대신 sed필요할 수 있습니다 .-r-E


그리고perl

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    perl -pe 's/(^[^"]*"|"[^"]*$)(*SKIP)(*F)|"/\\"/g'
label="123 \"456\" 789\" \"AB C" e f gh

여기서는 첫 번째부터 시작하는 문자열 과 마지막 부터 줄 끝까지의 "문자열은 다음과 같습니다."뛰어 넘다나머지는 다음 "으로 대체됩니다.\"

답변2

sed구조하러 오세요.

sed 's/"/\x1b"/g;s/\x1b"/"/;s/\(.*\)\x1b"/\1"/'

모든 인용문을 로 바꾼 ESC"다음 다시 방문하여 첫 번째 인용문을 인용문으로, 마지막 인용문을 인용문으로 바꿉니다. 상세 설명:

  • s/"/\x1b"/g: 모든 따옴표 문자를 \x1b(ESC) 및 따옴표로 바꿉니다.

  • s/\x1b"/"/: 첫 번째 \x1b(ESC)와 따옴표 조합을 작은따옴표로 바꿉니다.

  • s/\(.*\)\x1b"/\1"/: 마지막 \x1b(ESC)와 따옴표 조합을 작은따옴표로 바꿉니다.

출력 예:

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh |sed 's/"/\x1b"/g;s/\x1b"/"/;s/\(.*\)\x1b"/\1"/'|od -c
0000000   l   a   b   e   l   =   "   1   2   3     033   "   4   5   6
0000020 033   "       7   8   9 033   "     033   "   A   B       C   "
0000040       e       f       g   h  \n
0000050
$

답변3

몇 단계를 거쳐 요청한 내용을 얻을 수 있는 방법이 있습니다.
변수에 문자열이 포함될 수 있다고 가정합니다(문자열에는 작은따옴표가 없음).

$ label='label=\"123 \"456\" 789\" \"AB C\" e f gh'

우리는 뒷부분을 잘라낼 수 있습니다 \":

$ front=${label%\\\"*}
$ echo "$front"
\"123 \"456\" 789\" \"AB C

그런 다음 첫 번째 항목까지 삭제하십시오 \".

$ mid=${front#*\"}
$ echo "$mid"
123 \"456\" 789\" \"AB C

모두 \"다음으로 바꾸십시오 \e".

$ final=${mid//\\\"/\\e}
$ echo "$final"
123 \e456\e 789\e \eAB C

마지막으로 원래 문자열은 printf를 사용하여 재구성되고 이스케이프됩니다.

$ printf "label=\"${front%%\\\"*}$final\"${label#"${front}"}\n"
label="123 456 789 AB C"" e f gh

$ printf "label=\"${front%%\\\"*}$final\"${label#"${front}"}\n" | od -vAn -t x1c
  6c  61  62  65  6c  3d  22  31  32  33  20  1b  22  34  35  36
   l   a   b   e   l   =   "   1   2   3     033   "   4   5   6
  1b  22  20  37  38  39  1b  22  20  1b  22  41  42  20  43  22
 033   "       7   8   9 033   "     033   "   A   B       C   "
  22  20  65  20  66  20  67  68  0a
   "       e       f       g   h  \n

관련 정보