포함된 행을 삭제하고 싶습니다.질소캐릭터의 인스턴스입니다. 이 경우 문자는 /
.
나는 프로그램을 사용하는 것을 선호합니다 sed
.
답변1
사용해야 하는 경우 sed
명령은 다음과 같습니다.
sed -E -- '\-^([^/]*/[^/]*){3}$-d'
하지만 사용할 필요가 없다면 sed
가장 간단한 해결책은 를 사용하는 것입니다 grep
.
이 명령의 N을 원하는 값으로 바꾸세요.질소:
egrep -vx '([^/]*/[^/]*){N}'
grep
이 작업을 수행하는 모든 줄을 표시 -v
하는 명령줄 옵션이 있습니다.grep
아니요정규식을 일치시킵니다. 따라서 다음 작업은 정확히 N개의 슬래시 문자가 포함된 행과 일치하는 정규식을 만든 다음 grep -v
해당 정규식을 사용하는 것입니다.
예는 다음 패턴입니다.
[^/]*/[^/]*
N 인스턴스는 패턴입니다.
([^/]*/[^/]*){N}
정확히 N개 인스턴스의 패턴은 다음과 같습니다.
^([^/]*/[^/]*){N}$
전체 줄에만 일치하는 패턴에 대한 명령줄 옵션 grep
도 있습니다 (예: 이 예).-x
그러므로 N을 3이라고 하자. 정규식은 인스턴스가 3개 있는 행만 안정적으로 일치합니까 /
?
$ cat << EOF | egrep -x '([^/]*/[^/]*){3}'
/
//
///
////
/stuff
/stuff/added
/stuff/added/
/stuff/added/to/
/stuff/added/to/each
/stuff/added/to/each/line
more/stuff
more/stuff/added
more/stuff/added/
more/stuff/added/to/
more/stuff/added/to/each
more/stuff/added/to/each/line
consecutive//slashes/
/consecutive//slashes/
/consecutive//slashes
///all in one place
all in one place///
all in ///one place
EOF
///
/stuff/added/
more/stuff/added/
consecutive//slashes/
/consecutive//slashes
///all in one place
all in one place///
all in ///one place
예, 정규 표현식이 올바른 줄과 일치했습니다. 이제 -v
플래그를 추가하기 만 하면 됩니다 .거르는라인을 일치시키고 일치하지 않는 라인을 표시합니다.
$ cat << EOF | egrep -vx '([^/]*/[^/]*){3}'
/
//
///
////
/stuff
/stuff/added
/stuff/added/
/stuff/added/to/
/stuff/added/to/each
/stuff/added/to/each/line
more/stuff
more/stuff/added
more/stuff/added/
more/stuff/added/to/
more/stuff/added/to/each
more/stuff/added/to/each/line
consecutive//slashes/
/consecutive//slashes/
/consecutive//slashes
///all in one place
all in one place///
all in ///one place
EOF
/
//
////
/stuff
/stuff/added
/stuff/added/to/
/stuff/added/to/each
/stuff/added/to/each/line
more/stuff
more/stuff/added
more/stuff/added/to/
more/stuff/added/to/each
more/stuff/added/to/each/line
/consecutive//slashes/
답변2
/
awk:를 사용하여 필드 구분자로 지정하고 n+1
필드를 찾을 수도 있습니다.
awk -F'/' -v n=3 'NF != n + 1' file
답변3
이 pbm을 사용할 수 있습니다. 다음과 같이:
$ perl -ne 'tr|/|/| == 3 || print' inp
여기에서는 Perl 함수의 속성을 사용하여 tr
입력 문자열(이 경우 현재 레코드)에 대해 수행된 번역 수를 반환합니다. 따라서 입력 레코드에 정확히 세 개의 슬래시가 있으면 해당 레코드를 인쇄하지 않지만 다른 모든 경우에는 인쇄합니다.
이번에 사용된 또 다른 방법은 다음 POSIX sed
과 같습니다.
$ sed -e 's:/:/:4;t' -e 's//\n/3' -e '/\n/d' inp
여기서는 먼저 슬래시가 3개 이상 있는지 테스트하고, 그렇다면 패턴 공간을 사용하여 sed 코드 끝으로 분기합니다. OTW, 3개 이하의 슬래시가 패턴 공간에 나타납니다. 이제 \n
패턴 공간에서 세 번째 슬래시가 개행 문자로 대체 될 수 있는지 테스트합니다 . 이 교체 후에 개행 문자가 표시되면 => 입력에 정확히 3개의 슬래시가 있습니다. 정확히 3개의 슬래시를 보고 싶지 않기 때문에 이 패턴 공간을 삭제합니다. OTW, 남은 것(=> 슬래시가 2개 이하인 패턴 공간)은 표준 출력으로 가져옵니다.
참고: 마지막 경우에는 대체가 실패했기 \n
때문에 찾을 수 없습니다 .s//\n/3
그것을 사용하는 또 다른 방법은 POSIX sed
다음과 같습니다:
$ sed -e h -e 's|[^/]||g' -e '/^.\{3\}$/d' -e g inp
슬래시가 아닌 모든 문자가 제거된 현재 레코드의 복사본을 저장합니다. 이제 패턴 공간에 정확히 3개의 문자가 있는지 확인합니다(실제로는 모두 슬래시입니다). 만약 그렇다면 즉시 삭제하겠습니다. OTW, 보류 상태에서 저장된 레코드를 호출한 다음 sed가 기본적으로 이를 인쇄합니다.
HTH.
답변4
한 가지 접근 방식은 다음과 같습니다.
교체해 보세요 (대체)(N+1)캐릭터가 처음으로 나타납니다 . 교체가 성공하면 새로운 주기가 시작됩니다(분기).
교체해 보세요 (대체)질소문자가 처음으로 나타납니다 . 교체가 실패하면 새 루프가 시작됩니다(분기).
(다른)
- 이 줄 삭제
GNU sed를 사용하고N = 2:
$ printf 'foo/\nfoo/bar/\nfoo/bar/baz/\n' | sed -e 's,/,/,3;t' -e 's,/,/,2;T' -ed
foo/
foo/bar/baz/