다른 유사한 질문을 살펴봤지만 답변이 도움이 되지 않았습니다. 저는 bash를 처음 접했고 스크립트에 구문 오류가 있을 수 있지만 어디에 있는지 모르겠습니다. 이 스크립트를 실행할 때마다 example.conf 파일의 사용자를 업데이트하려고 합니다. 각 사용자에게는 name.pub 파일이 있습니다.
VAR1=$( ls | grep ".pub" |sed "s/.pub//g")
VAR2="@demo_project_users = "
res=$VAR2$VAR1
sed "s/@demo_project_users = .*/$res/g" example.conf
이렇게 하면 Unterminated 's' command
오류가 발생합니다.
편집: 이 파일들을 폴더에 넣었습니다
aaaaaaaaaa.pub eboh.pub get_usernames.sh mmusterfrau.pub plom.pub rrein.pub update_users.sh
dboh.pub example.conf leni.pub mmustermann.pub rcall.pub tani.pub
아래와 같이 사이에 공백을 두고 모든 사용자 이름(.pub 제외)을 한 줄에 입력하고 싶습니다.
@demo_project_users = (... all names here)
답변1
파일 grep
이름은 주어진 값에 $res
개행 문자가 포함된 여러 파일 이름과 일치할 수 있습니다. sed
리터럴 개행 문자가 포함된 대체 문자열을 사용할 때 GNU는 설명하는 방식으로 불평합니다.
grep
필터링된 출력 에는 사용하지 마십시오 ls
. 패턴과 일치하는 현재 디렉토리의 모든 이름을 얻으려면 *.pub
다음을 사용하십시오.
filenames=( *.pub )
그러면 주어진 패턴과 일치하는 모든 이름을 포함하는 배열이 생성됩니다.
그 다음에:
sed 's/\(@demo_project_users = \).*/\1'"${filenames[*]%.pub}"'/g' example.conf
Expand는 "${filenames[*]%.pub}"
배열의 각 파일 이름으로 구성된 단일 문자열로 확장되고 filenames
공백(또는 첫 번째 문자가 무엇 $IFS
이든 기본적으로 공백) 으로 구분되며 .pub
각 파일 이름에서 접미사 문자열을 제거합니다.
"${filenames[*]}"
공백으로 구분된 문자열로 확장되는 비트와 %.pub
각 파일 이름에서 접미사를 제거하는 비트 입니다 ..pub
답변2
$res
명령 대체는 쉘에 의해 수행됩니다. 값에 슬래시가 있으면 sed는 그것이 명령의 끝이 아니라는 것을 알 수 없습니다 s
. 마찬가지로 sed는 백슬래시나 & 기호를 $res
특수 문자로 해석합니다 .
백슬래시와 앰퍼샌드를 사용할 수 없고 $res
다른 문자도 사용할 수 없다는 것을 알고 있는 경우 해당 문자를 구분 기호로 사용하십시오. 예를 들어:
sed "s~@demo_project_users = .*~$res~g" example.conf
또는 특수 문자 앞에 백슬래시를 추가하여 인용하십시오.
quoted_res=$(printf %s "$res" | sed 's/[\\\/&]/\\&/g')
sed "s/@demo_project_users = .*/$quoted_res/g" example.conf