저는 FreeBSD를 실행하는 공유 호스트인 내 서버용 쉘 스크립트를 작성하고 있습니다. 또한 Linux를 실행하는 PC에서 로컬로 테스트할 수 있기를 원합니다. 그래서 이식 가능한 방식으로 작성하려고 하는데 sed
그렇게 할 수 있는 방법이 없는 것 같습니다.
내 웹 사이트의 일부는 생성된 정적 HTML 파일을 사용하며 다음 sed 줄은 각 재생성 후에 올바른 DOCTYPE을 삽입합니다.
sed -i '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
이는 Linux의 GNU와 함께 작동 sed
하지만 FreeBSD는 sed
옵션 뒤의 첫 번째 인수가 -i
백업 복사본의 확장일 것으로 예상합니다. 다음과 같습니다.
sed -i '' '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
그러나 GNU는 sed
표현식이 즉시 뒤따를 것으로 예상합니다 -i
. (개행 처리도 수정해야 하지만 이는 이미여기)
물론 이 변경 사항을 스크립트의 서버 복사본에 포함할 수 있지만 그렇게 하면 VCS를 사용하여 버전 제어가 엉망이 됩니다. sed를 사용하여 완전히 이식 가능한 방식으로 이를 달성할 수 있는 방법이 있습니까?
답변1
GNU sed는 -i
중간 공백 없이 동일한 인수에 있어야 하는 .extensions를 허용합니다. 이 구문은 FreeBSD sed에서도 작동합니다.
sed -i.bak -e '…' SOMEFILE
FreeBSD에서는 -i
입력 파일이 여러 개인 경우에도 동작이 변경됩니다. 즉, 입력 파일은 독립적으로 처리됩니다(예: $
각 파일의 마지막 줄 일치). 그리고 이것은 BusyBox에서는 작동하지 않습니다.
백업 파일을 사용하지 않으려면 사용 가능한 sed 버전을 확인하세요.
# Assume that sed is either FreeBSD/macOS or GNU
case $(sed --help 2>&1) in
*GNU*) set sed -i;;
*) set sed -i '';;
esac
"$@" -e '…' "$file"
또는 위치 매개변수가 깨지는 것을 방지하려면 함수를 정의하세요.
case $(sed --help 2>&1) in
*GNU*) sed_i () { sed -i "$@"; };;
*) sed_i () { sed -i '' "$@"; };;
esac
sed_i -e '…' "$file"
귀찮게하고 싶지 않다면 Perl을 사용하십시오.
perl -i -pe '…' "$file"
이식 가능한 스크립트를 작성하려면 사용하지 마십시오. -i
POSIX에는 없습니다. sed가 뒤에서 수행하는 작업을 수동으로 수행합니다. 코드 한 줄만 더 있으면 됩니다.
sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"
답변2
게임을 더 좋게 만들기 위한 팁을 찾을 수 없다면 sed
다음을 시도해 보세요.
사용하지 마세요
-i
:sed '1s/^/<!DOCTYPE html> \n/' "${file_name.html}" > "${file_name.html}.tmp" && mv "${file_name.html}.tmp" "${file_name.html}"
펄 사용하기
perl -i -pe 'print "<!DOCTYPE html> \n" if $.==1;' "${file_name.html}"
답변3
편집하다
를 사용하면 언제든지 ed
기존 파일 앞에 줄을 추가할 수 있습니다.
$ printf '0a\n<!DOCTYPE html>\n.\nw\n' | ed my.html
세부 사항
주변 비트는 해당 행을 파일에 추가하라는 <!DOCTYPE html>
명령입니다 .ed
my.html
sed
sed
나는 이 명령 도 작동할 것이라고 믿습니다 :
$ sed -i '1i<!DOCTYPE html>\n` testfile.csv
답변4
FreeBSDsedMac OS X에서도 사용되는 토글 -e
옵션은 -i
다음(정규식) 명령을 정확하고 명확하게 정의하고 인식하는 데 필요합니다.
즉, sed -i -e ...
FreeBSD 및 GNU와 함께 사용해야 합니다 sed
.
보다 일반적으로 FreeBSD 이후 백업 확장을 생략하려면 명령줄 인수를 구문 분석할 때 FreeBSD 부분의 혼동을 피하기 위해 sed -i
명시적인 옵션이나 스위치가 필요합니다 .sed
-i
sed
(그러나 내부 sed
파일 편집으로 인해 파일 inode가 변경된다는 점에 유의하십시오."제자리에서" 파일 편집).
(일반적으로 최신 버전의 FreeBSD는 GNU와의 호환성을 높이기 위해 전환 sed
되었습니다 .)-r
sed
echo a > testfile.txt
ls -li testfile.txt
#gsed -i -e 's/a/A/' testfile.txt
#bsdsed -i 's/a/A/' testfile.txt # does not work
bsdsed -i -e 's/a/A/' testfile.txt
ls -li testfile.txt
cat testfile.txt