패턴을 기반으로 텍스트 파일에서 줄을 삭제해야 하지만 처음 n 줄은 패턴과 일치하도록 유지해야 합니다.
입력하다
% 1
% 2
% 3
% 4
% 5
text1
text2
text3
산출
%1
%2
text1
text2
text3
파일을 사용했지만 sed /^%/d
%로 시작하는 모든 줄을 제거했는데 sed 3,/^%/d
그것도 작동하지 않았습니다. 패턴의 처음 n개 행을 유지하고 나머지는 삭제해야 합니다.
답변1
% put으로 시작하는 모든 줄을 삭제하고 처음 두 줄의 입력을 유지하려면 다음을 수행하십시오.
sed -e 1,2b -e '/^%/d'
다음을 사용하는 것이 더 명확하지만 awk
:
awk 'NR <= 2 || !/^%/'
또는 공연을 마친 후인 경우:
{ head -n 2; grep -v '^%'; } < input-file
입력의 첫 번째 줄이 아닐 수도 있는 처음 두 줄을 패턴과 일치하게 유지하려면 다음이 awk
확실히 더 나은 옵션입니다.
awk '!/^%/ || ++n <= 2'
을 사용하려면 sed
다음 기술을 사용할 수 있습니다.
sed -e '/^%/!b' -e 'x;/xx/{h;d;}' -e 's/^/x/;x'
즉, 예약된 공간을 이용하여 현재까지 일치하는 패턴의 발생 횟수를 센다. 효율적이지 않고 명확하지 않습니다.
답변2
이 작업을 혼자 수행하기에는 너무 간단할 것 같습니다 sed
(불가능하지는 않지만 다소 복잡합니다. 예를 들어sed 푸시 박스무엇을 할 수 있는지).
어때요 awk
?
#!/bin/awk -f
BEGIN { c = 0; }
{
if (/^%/) {
if (c++ < 3) {
print;
}
} else {
print;
}
}
최신 BASH(정규 표현식 지원)를 사용할 수 있다면 위의 awk는 다음과 같이 번역될 수 있습니다.
#!/bin/bash -
c=0
while IFS= read -r line; do
if [[ $line =~ ^% ]]; then
if ((c++ < 3)); then
printf '%s\n' "$line"
fi
else
printf '%s\n' "$line"
fi
done
패턴 일치를 위해 연산자 대신 sed
또는를 사용할 수도 있습니다 .grep
=~
답변3
진주한 줄해결책:
# in-place editing
perl -i -pe '$.>2 && s/^%.*//s' filename.txt
# print to the standard output
perl -ne '$.>2 && /^%/ || print' filename.txt
답변4
sed '/^%/{
3,$d}' '% 1
% 2
% 3
% 4
% 5
text1
text2
text3'
불필요한 선을 제거하는 방법입니다.
편집: 내 대답은 s 와 동일한 조건에서 작동하며 Stephane Chazelas
% 줄이 먼저 나오지 않으면 작동하지 않습니다.
너드 저격.
sed -n '/^% [^12]*$/!{
/^% [12][[:digit:]]\{1,\}/n
p}' file.txt
% number
이는 스트림에서 문자열이 발견되는 위치 에 관계없이 작동합니다. %
또는 이외의 문자 수로 시작하고 끝나는 줄은 무효화됩니다 . 주소는 사각지대를 제외하고는 모두 일치했습니다. 10-29 사이의 숫자는 계속 인쇄됩니다. 따라서 범위와 일치하도록 두 번째 주소를 중첩하고 줄을 건너뜁니다.1
2
/% [A-Za-z3-9]*/
하지만 여전히 더 나을 것입니다.