sed -i(제자리에서 편집)를 사용하여 이식성을 달성하는 방법은 무엇입니까?

sed -i(제자리에서 편집)를 사용하여 이식성을 달성하는 방법은 무엇입니까?

저는 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"

이식 가능한 스크립트를 작성하려면 사용하지 마십시오. -iPOSIX에는 없습니다. sed가 뒤에서 수행하는 작업을 수동으로 수행합니다. 코드 한 줄만 더 있으면 됩니다.

sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"

답변2

게임을 더 좋게 만들기 위한 팁을 찾을 수 없다면 sed다음을 시도해 보세요.

  1. 사용하지 마세요 -i:

    sed '1s/^/<!DOCTYPE html> \n/' "${file_name.html}" > "${file_name.html}.tmp" &&
      mv "${file_name.html}.tmp" "${file_name.html}"
    
  2. 펄 사용하기

    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>명령입니다 .edmy.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-ised

(그러나 내부 sed파일 편집으로 인해 파일 inode가 변경된다는 점에 유의하십시오."제자리에서" 파일 편집).

(일반적으로 최신 버전의 FreeBSD는 GNU와의 호환성을 높이기 위해 전환 sed되었습니다 .)-rsed

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

관련 정보