나는 변수를 사용해 보았습니다 (행 위치)을 파일을 "잘라내기" 위한 인수로 사용했지만 sed 명령에서 오류가 발생했습니다.
이것은 내 코드입니다.
START=$(grep -n "pattern1" $FILE | cut -f1 | sed 's/:.*$//g')
END=$(grep -n "pattern2" $FILE | cut -f1 | sed 's/:.*$//g')
sed -n '${START},${END}p' $FILE > temp; # error here
# sed: -e expression #1, char 3: unknown command: `S'
하지만 숫자를 사용할 때는 작동합니다.
sed -n '28,63p' $FILE > temp;
일부 이스케이프를 적용해야 할 것 같지만 알 수 없습니다. 어떤 제안이 있으십니까? 매우 감사합니다!
답변1
START
코드의 주요 문제점은 쉘이 작은따옴표로 묶인 문자열로 및 변수를 확장할 것으로 예상한다는 것입니다 . END
쉘은 이것을 결코 수행하지 않으며 이것이 작은따옴표와 큰따옴표 문자열 사이의 주요 차이점 중 하나입니다.
대신 표현식에 큰따옴표로 묶인 문자열을 사용하세요 sed
.
그러나 두 파이프가 각각 행 번호를 반환할 것으로 예상하는 것 같습니다 grep
. 이 경우 이 양식을 직접 실행할 수 있으므로 그 이유를 알 수 없습니다 sed
. sed
명령이 두 개 이상의 주소를 사용하는 경우 명령은 주소를 행 번호, 정규식 또는 이러한 형식의 조합으로 사용합니다.
sed -n '/pattern1/,/pattern2/ p' "$FILE" >temp
또는
sed '/pattern1/,/pattern2/ !d' "$FILE" >temp
아마도 grep
파이프를 유지해서는 안 되지만, 줄 번호를 직접 반환하는 것으로 줄일 수 있다는 점을 추가하기 위한 것입니다 sed
.
start=$( sed -n '/pattern1/ { =; q; }' )
위의 내용은 패턴과 일치하는 첫 번째 줄의 줄 번호를 제공합니다 pattern1
. =
현재 라인번호를 출력하는 명령어 입니다 .
답변2
설명한 대로 큰따옴표로 변경해야 하지만 파일에 패턴이 두 배 이상 있으면 원본 스크립트도 손상됩니다. 위의 솔루션은 훌륭하게 작동하며 시작/끝 패턴 사이의 각 줄을 인쇄합니다. 이 한 줄의 코드는 첫 번째 항목만 인쇄합니다.
sed -n '/pattern1/{:loop;p;/pattern2/q;N;s/.*\n//;b loop};' "$file"