별칭 함수에서 변수의 올바른 대체

별칭 함수에서 변수의 올바른 대체

파일에서 입력한 줄을 제거하는 별칭 함수를 만들려고 합니다.

function remove_line(){
       line_to_remove="'s/^"$1"$//g'"
       sed -i $(line_to_remove) my_file
}

예: remove_line domain.com이 도메인은 지정된 파일에서 제거되어야 합니다.

그러나 $정확한 설명은 없는 것 같습니다. 내가 뭘 잘못했나요?

답변1

귀하의 주요 질문 $(line_to_remove)명령 대체, 즉 괄호 안의 명령에 의해 출력된 텍스트로 대체된 표현식입니다( line_to_remove이로 인해 "명령을 찾을 수 없음" 오류가 발생할 것으로 예상됩니다). 당신은 그것을 사용하고 싶을 수도 있습니다 "$line_to_remove".

그러나 sed대체 표현식에 쉘 변수를 삽입하는 것은 삽입된 문자열에 너무 많은 조건을 지정하기 때문에 이상적이지 않습니다(유효한 정규 표현식이어야 하며 /다음을 포함할 수 없습니다).

grep대신, 표준 출력에 결과를 사용하고 쓰거나 임시 파일에 쓰거나 성공적인 실행 후 원본 파일을 바꾸는 것이 좋습니다 . 또는 (GNU moreutils 패키지에서) 원본 파일을 덮어쓰 grep도록 할 수도 있습니다 .sponge

remove_lines () {
       grep -v -Fx -e "$1" my_file | sponge my_file
}

여기에 사용된 옵션은 grep함수의 첫 번째 인수로 지정된 행이 정규 표현식이 아닌 있는 그대로 사용되어 처음부터 끝까지 행이 일치하고 입력에서 일치하는 행이 제거되도록 보장합니다.

아니요 sponge:

remove_lines () {
       tmpfile=$(mktemp)
       grep -v -Fx -e "$1" my_file >"$tmpfile" && mv "$tmpfile" my_file
       rm -f "$tmpfile"
}

mv성공할 경우에만 실행되며 실패 grep할 경우 임시 파일은 삭제됩니다 rm -f.


개인적으로 저는 아마도 다음과 같이 함수를 작성할 것입니다.

remove_lines () {
       grep -v -Fx -e "$1"
}

이를 통해 사용자는 다음과 같이 사용할 수 있습니다.

remove_lines "my line" <my_file | sponge my_file

some-command | remove_lines "bumble bee" | other-command

이렇게 하면 함수가 필터 역할을 하게 됩니다.그냥 주석에 적힌대로 하세요즉, 입력에서 행을 제거하고 입력이 어디서 왔고 어디로 가는지는 신경 쓰지 않습니다.

관련 정보