텍스트 파일에서 문자열의 상위 집합 제거

텍스트 파일에서 문자열의 상위 집합 제거

디렉터리 목록이 포함된 파일이 있습니다.

/a/b
/a/b/c /a/b/
d /a/ b /
e
/a/c
/a/c/b
/a/c/d
/a/d/e
/a/d/e /f /a/e/f/g /a/e/ f
/g /
h
...

나는 /a/b, /a/c, /a/d/e 및 /a/e/f/g만을 얻고 싶습니다. 즉, 다른 줄의 하위 집합이 앞에 오는 줄을 제외하고 싶습니다. 하위 디렉터리의 깊이는 임의적이므로 2, 3, 4 등으로 내려가서 고유한 하위 디렉터리를 찾을 수 있습니다.

답변1

입력이 정렬되었다고 가정하고 접두어를 확인하고 변경되면 업데이트하는 것은 어떻습니까?

$ awk 'NR == 1 || ! match($0, "^" pfx) {print; pfx = $0}' file
/a/b
/a/c

참고: 이는 정규식 일치이므로 항목에 정규식 특수 문자가 포함된 경우 적합하지 않을 수 있습니다. FWIW는 이 컨텍스트에서 특수 문자로 처리되지 않거나 처리되지 gawk않는 mawk것 같습니다./

답변2

gawk -F/ '
    {
        # have we seen something that is a prefix of this line?
        for (prefix in prefixes)
            if ($0 ~ "^" prefix)
                # yes we have
                next

        prefixes[$0] = 1

        # are there prefixes that get "cancelled out" by this new one?
        # e.g. /a/b/c is already a prefix but current line is /a/b
        for (prefix in prefixes)
            if (prefix ~ "^" $0 ".+")
                delete prefixes[prefix]
    }
    END {
        # GNU awk: traverse the array by index, sorted
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (p in prefixes)
            print p
    }
' list_of_dirs

산출

/a/b
/a/c
/a/d/e
/a/e/f/g

GNU awk가 없으면 출력을 다음으로 파이프하십시오.| sort

답변3

$ awk -F/ 'NF==3 { print }' filename

필드 구분 기호를 로 설정한 /다음 세 개의 필드만 포함하는 줄을 인쇄합니다. 입력 파일이 일관된 형식이라고 가정하면 다음 과 /a/b같은 줄만ab

답변4

편집기를 사용하여 sed다음과 같이 이 작업을 수행할 수 있습니다.

$ sed -e '
   $!N
   \|^\(.*\)\n\1/|!{P;D;}
   s/\n.*//;H;s/.*//;x;D
' input_file

/a/b
/a/c
/a/d/e
/a/e/f/g

피복재:

  1. 패턴 공간에는 항상 두 줄이 있는지 확인하세요.
  2. 첫 번째 부분이 패턴 공간의 두 번째 부분의 선행 위치에서 발견되지 않으면 => 동일한 분기에 속하지 않습니다. 첫 번째 부분을 인쇄하고 삭제한 다음 돌아가서 다음 줄을 패턴 공간으로 읽어 동일한 검사를 수행합니다.
  3. 일치하는 경우 두 번째 부분을 삭제하고, 이것이 더 큰 부분이므로(정렬된 입력 가정으로 인해) 해당 부분을 즉시 삭제합니다. 그런 다음 돌아가서 다음 줄을 패턴 공간으로 읽은 다음 헹구고 반복하십시오.

입력이 정렬되지 않은 경우 다음과 같이 수행할 수 있습니다.

$ perl -lne '
    my $l = $_;
    grep !index($l,$_), keys %h or $h{$_}++;
    }{print for sort keys %h;
' input
/a/b
/a/c
/a/d/e
/a/e/f/g

피복재:

  • index(str, substr)은 str에서 substr이 발견된 인덱스를 반환합니다. 처음부터 일치시키려면 0을 반환한 다음 성공으로 읽히도록 부울 값을 반전합니다. grep은 키가 우리가 원하는 하위 문자열인 해시 %h의 모든 현재 키를 반복합니다.

관련 정보