SED - 줄 번호를 텍스트 파일의 새 텍스트 및 변수로 바꿉니다.

SED - 줄 번호를 텍스트 파일의 새 텍스트 및 변수로 바꿉니다.

Bash에서 사용하는 데 문제가 있습니다 sed. 누구든지 도와주실 수 있나요? 이 sed명령은 잘 작동합니다 ...

sed주문하다

sed -i '3s/.*/...test_text.../g' FILE.txt

sed명령+변수

하지만 SED의 변수를 새 텍스트, 새 줄로 사용하면 오류가 발생합니다... sed -e #expression #1, `s'에 대한 알 수 없는 옵션

line_number="3"
new_text="...test_text..."
FILE="FILE.txt"
sed -i "${line_number}s/.*/${new_text}/" $FILE

설명을 도와주실 수 있나요? 문제가 무엇이며 어떻게 작성해야 하나요? 다른 많은 버전을 시도했고 다른 빨간색 테마도 있는데... 계속 멈췄습니다. 미리 도움을 주셔서 감사합니다...

답변1

변수에 슬래시가 포함된 경우 new_text이를 sed명령에 삽입하면 내부 표현식 구문 분석기에 의해 구문 오류가 생성됩니다 sed.

s해결 방법은 쉼표와 같은 다른 문자를 명령 구분 기호로 사용하는 것입니다 .

sed -i "$line_number s,.*,$new_text," "$file"

값이 new_text너무 다양하여 문자열에 표시되지 않는 구분 기호를 안정적으로 선택할 수 없는 경우 이 c명령을 사용하는 것이 좋습니다. c(변경) 명령을 사용하여 행을 바꿀 수 있습니다 .

sed -i "$line_number c \\$new_text" "$file"

이 명령은 ca 및 개행 문자 뒤에 새 텍스트를 가져옵니다. GNU에서는 \개행 문자가 선택 \사항인 것으로 보입니다 sed. 위의 내용을 사용하여 백슬래시로 시작할 \수 있도록 하고 $new_text, 큰따옴표로 묶인 문자열에 있으므로 다른 백슬래시로 이스케이프 처리합니다.

이식 가능한 sed명령은 다음과 같아야 합니다.

sed "$line_number c \\
$new_text" "$file"

위의 내용에서는 각 개행 문자 $new_text앞에 \문자가 오고 데이터의 일부인 리터럴 백슬래시가 이스케이프된다고 가정합니다 \\.


awk아래에서는 GNU를 사용하여 awk내부 편집을 활성화할 수도 있습니다.

text=$new_text awk -i inplace -v lineno="$line_number" \
    'NR == lineno { print ENVIRON["text"]; next }; 1' "$file"

GNU를 제외하고 는 새 텍스트가 에 있고 줄 번호가 에 있으며 파일의 경로 이름이 에 있다고 awk가정합니다 .$new_text$line_number$file

새 텍스트는 환경 변수를 통해 text코드에 전달되고 awk, 줄 번호는 명령줄의 내부 변수에 전달됩니다 awk. lineno주어진 줄 번호가 발견되면 코드는 text현재 줄을 인쇄하는 대신 환경 변수의 값을 인쇄합니다.

이러한 방식으로 awkGNU 쌍 값을 사용하는 데에는 특별한 제한이 없습니다 $new_text.

예( awk내 시스템에서는 GNU라고 함 gawk):

$ cat file.txt
Line 1
Line 2
Line 3
$ new_text='hello world'
$ line_number=2
$ file=./file.txt
$ text=$new_text gawk -i inplace -v lineno="$line_number" \
    'NR == lineno { print ENVIRON["text"]; next }; 1' "$file"
$ cat file.txt
Line 1
hello world
Line 3

답변2

위와 같이 변수와 명령어를 입력하면 오류가 발생하지 않습니다. 문제는 실제 내용에 있다 new_text. 내 생각엔 이것 과 같은 슬래시 가 포함된 것 같아요 new_text=usr/bin. 그런 다음 변수를 교체하면 다음과 같은 결과가 나타납니다.

sed -i "3s/.*/usr/bin/" FILE.txt

따라서 해당 행은 으로 대체되고 usr계속 sed해서 명령의 플래그를 해석 하고 합법적인 옵션이 아닌 를 찾습니다 s.bbin

유효한 문자 범위를 알고 있는 경우 new_text해당 범위 밖의 문자를 구분 기호로 선택하세요.

sed -i "${line_number}s~.*~${new_text}~" $FILE

관련 정보