나는 대답했다이 문제, 그런데 작은따옴표를 추가해야 하는 부분에서 막혔습니다.
원본 파일과 같습니다.
$$BATCHCTRL=TEST-012017
$$STATE=CA AZ
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
새 파일은 다음과 같아야 합니다.
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
나는 사용했다
sed -Ei 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/\$\$STATE=\1/g' sed_file
그래서 나는 다음을 얻습니다:
$$BATCHCTRL=TEST-012017
$$STATE=CA
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
하지만 이제는 작은따옴표를 추가할 수 없습니다. 작은 따옴표 대신 큰 따옴표를 사용하여 이스케이프를 시도하고 따옴표를 사용하지 않으려고 시도했지만 그 중 아무 것도 작동하지 않습니다.
답변1
두 가지 옵션:
작은 따옴표로 묶인 문자열을 표현식으로 일시적으로 중단하고 (따옴표로 묶인 작은 따옴표 문자)를 sed
삽입한 후 계속하세요. "'"
다른 인용문에도 반복합니다.
$ sed -E 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/$$STATE='"'"'\1'"'"'/' file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
$
대체 문자열에서 이스케이프 할 필요는 없습니다.
\'
대신 사용할 수도 있습니다 "'"
.
$ sed -E 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/$$STATE='\''\1'\''/' file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
또는,
표현식 주위에는 큰따옴표를 사용하고 그 안에는 작은따옴표를 일반 문자로 사용하십시오. 이를 위해서는 $
기존의 모든 백슬래시와 문자를 셸에서 보호해야 합니다.
$ sed -E "s/^\\\$\\\$STATE=([A-Z]{2}) ([A-Z]{2})/\$\$STATE='\1'/" file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
정규식에서 리터럴 문자열 sed
(및 대체 부분의 리터럴 문자열)을 가져오려고 하므로 여기서는 너무 많은 이스케이프가 필요합니다. 셸의 큰따옴표 내에서는 단지 리터럴일 뿐입니다. 백슬래시 뒤에 가 붙고 쉘은 확장(또는 예)으로 다음에 오는 모든 것을 사용하려고 시도합니다. 사용하여 리터럴 백슬래시와 리터럴을 제공합니다.\$
$
\$
$
\\$
$
$
$$
$STATE
\\\$
$
.g
sed
줄의 시작 부분에 고정하고 있으므로 교체가 두 번 이상 수행될 것으로 예상하지 않습니다.
답변2
bash
FWIW, 다음을 사용하여 명령줄 호출 sed
에서 작은따옴표 안의 더하기 기호를 바꿀 수 있습니다 .
$ sed -e 's/$$STATE=\([A-Z][A-Z]\) [A-Z][A-Z]$/$$STATE='"'\1'/" sed_file
이렇게 하면 "과도한 백슬래시"("백슬래시염"을 유발하는 것으로 알려져 있음)를 피할 수 있습니다.
고려해야 할 몇 가지 사항이 있습니다.
$
s/// 명령의 lhs에서 마지막 항목을 제외한 다른 위치에서 사용하면 메타 문자 상태가 손실됩니다. 물론, 작은따옴표로 묶어야 합니다. bash는 어쨌든 변수를 시작하고 확장합니다. 나는 sed가 하는 일에 대해 이야기하고 있습니다.s/// 명령의 오른쪽에 있는 $는 메타 문자가 아니므로 이스케이프할 필요가 없습니다.
sed는 -re 모드 대신 -e 모드에 있습니다.
화타이
답변3
나는 다음을 시도했다
sed "/^\$\$STATE/s/ .*/'/g" filename| sed "/\$\$STATE/s/=/&'/g"
산출
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/201