
파일에서 입력된 줄을 제거하는 별칭 함수를 만들려고 합니다.
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
이렇게 하면 함수가 필터로 작동하게 됩니다.주석에 적힌 대로만 수행합니다.즉, 입력에서 라인을 제거하고 입력이 어디서 오고 어디로 가는지 신경 쓰지 않습니다.