FreeBSD를 실행하는 공유 호스팅 인 서버용 셸 스크립트를 작성하고 있습니다. 또한 Linux를 실행하는 PC에서 로컬로 테스트하고 싶습니다. 따라서 이식 가능한 방식으로 작성하려고하지만 sed
그렇게 할 방법이 없습니다.
내 웹 사이트의 일부는 생성 된 정적 HTML 파일을 사용하며이 sed 행은 각 재생성 후에 올바른 DOCTYPE을 삽입합니다.
sed -i '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
sed
Linux에서는 GNU와 함께 작동 하지만 FreeBSD sed
는 -i
옵션 이후의 첫 번째 인수 가 백업 사본의 확장이 될 것으로 예상합니다 . 이것이 다음과 같이 보일 것입니다 :
sed -i '' '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
그러나 GNU sed
는 그식이 바로 뒤에 이어질 것으로 예상합니다 -i
. (또한 개행 처리로 수정해야하지만 이미 여기에 답변되어 있습니다 )
물론 서버의 스크립트 사본에이 변경 사항을 포함시킬 수 있지만 버전 관리를 위해 VCS를 사용하는 것은 혼란 스러울 것입니다. sed로 완전히 이식 가능한 방법으로 이것을 달성 할 수있는 방법이 있습니까?
답변
GNU sed는 이후에 선택적 확장을 허용합니다 -i
. 확장은 중간에 공백이없는 동일한 인수에 있어야합니다. 이 구문은 BSD sed에서도 작동합니다.
sed -i.bak -e '…' SOMEFILE
BSD에서는 -i
입력 파일이 여러 개인 경우 동작이 변경됩니다. 파일은 독립적으로 처리됩니다 (예 : $
각 파일의 마지막 행과 일치). 또한 이것은 BusyBox에서 작동하지 않습니다.
백업 파일을 사용하지 않으려면 사용 가능한 sed 버전을 확인할 수 있습니다.
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"
답변
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}"
답변
에드
항상 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
답변
perl -i
후드에서 수행하는 작업을 수동으로 수행 할 수도 있습니다 .
{ rm -f file && { echo '<!DOCTYPE html>'; cat; } > file;} < file
마찬가지로 perl -i
백업이 없으며 여기에 제공된 대부분의 솔루션과 마찬가지로 파일의 권한, 소유권에 영향을 줄 수 있으며 심볼릭 링크를 일반 파일로 바꿀 수 있습니다.
와:
sed '1i\
<!DOCTYPE html>' file 1<> file
sed
파일 자체를 덮어 쓰므로 소유권과 권한 또는 심볼릭 링크에 영향을 미치지 않습니다. 일반적으로 명령으로 덮어 쓰기 전에 (내 경우에는 4k)에서 데이터로 가득 찬 버퍼를 읽었 sed
으므로 GNU와 함께 작동합니다 . 파일이 출력을 버퍼링 한다는 사실을 제외하고 파일이 4k를 초과하면 작동하지 않습니다 .sed
file
i
sed
기본적으로 sed
읽기 및 쓰기를 위해 4k 블록에서 작동합니다. 삽입 할 줄이 4k보다 작 으면 sed
아직 읽지 않은 블록을 덮어 쓰지 않습니다.
나는 그것에 의존하지 않을 것입니다.
답변
Mac OS X에서도 사용되는 FreeBSD sed 는 다음 (regex) 명령을 정확하고 명확하게 정의하고 인식하기 -e
위해 -i
스위치 뒤에 옵션이 필요합니다 .
즉, sed -i -e ...
FreeBSD & GNU 모두에서 작동해야합니다 sed
.
보다 일반적으로 FreeBSD 이후 백업 확장을 생략 sed -i
하려면 명령 행 인수를 구문 분석하는 동안 FreeBSD의 일부에서 혼동을 피하기 위해 sed
다음과 같은 명시적인 옵션 또는 스위치 가 필요합니다 .-i
sed
그러나, sed
내부 파일 편집은 파일 inode 변경으로 이어집니다 (파일의 “제자리”편집 참조 ).
일반적인 힌트로, 최신 버전의 FreeBSD sed
에는 -r
GNU와의 호환성을 높이는 스위치가 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
답변
sed -i
경쟁 조건을 최대한 피하면서 단일 파일을 이식 가능하게 에뮬레이트하려면 다음을 수행하십시오.
sed 'script' <<FILE >file
$(cat file)
FILE
그건 그렇고, 이것은 sed -i
디렉토리 및 파일 권한에 따라 sed -i
사용자가 편집 권한이없는 파일을 덮어 쓸 수있게하는 가능한 문제를 처리합니다 .
다음과 같은 백업을 수행 할 수도 있습니다.
sed 'script' <<FILE >file
$(tee file.old <file)
FILE
답변
Ex 모드에서 Vim을 사용할 수 있습니다 :
ex -sc '1i|<!DOCTYPE html>' -cx file
-
1
첫 줄을 선택하십시오 -
i
텍스트와 개행 삽입 -
x
저장하고 닫습니다
또는 주석에서와 같이 평범한 오래된 표준 ex
:
printf '%s\n' 1i '<!DOCTYPE html>' . x | ex file