grep을 사용하여 ls 출력을 필터링할 때 예기치 않은 결과가 발생함

grep을 사용하여 ls 출력을 필터링할 때 예기치 않은 결과가 발생함

현재 grep문제를 사용하고 해결 중입니다 ls. 목표는 링크된 파일인 현재 디렉토리의 모든 행을 나열하는 것입니다. 내 디렉토리에 3개의 연결된 파일이 있지만 명령을 실행하면 하나만 표시됩니다.

내가 입력하는 내용은 다음과 같습니다.

ls -lR | grep l*

어떤 도움이라도 대단히 감사하겠습니다. 감사해요

답변1

@NasirRiley가 올바른 길을 가고 있습니다. 현재 디렉터리의 기호 링크를 나열하려면 find . -mindepth 1 -maxdepth 1 -type l.test를 실행하세요.

$ cd "$(mktemp --directory)"
$ mkdir foo
$ touch foo/bar baz
$ ln --symbolic foo/bar ban
$ ln --symbolic bar foo/bat # symlink in subdirectory, should be ignored
$ find . -mindepth 1 -maxdepth 1 -type l
./ban

답변2

파이프에 몇 가지 문제가 있습니다.

  1. 출력 구문 분석ls 이건 좋은 생각이 아니야(당신은 또한 볼 수 있습니다왜 `ls`를 구문 분석하지 *않나요*(그리고 어떻게 수행합니까)?). 해당 형식은 표준화되지 않았으며 파일 이름에는 NUL 및 /. 종종 주어진 예제에는 개행 문자가 포함됩니다. ( ls다르게 호출하면 모호할 수도 있는 다른 결과가 발생할 수 있습니다.)

    $ touch 'foo
    > bar'
    $ ls -1
    'foo'$'\n''bar'
    $ ls | cat
    foo
    bar
    

    foo두 개의 다른 파일이 있거나 bar동일한 파일 이름의 두 부분이 있습니까?

    특정 유형의 파일을 디렉토리에서 재귀적으로 검색하는 안전한 방법은 다음과 같습니다.find.

  2. 이스케이프되지 않은 문자열은 l*쉘에서 다음과 같이 해석됩니다.와일드카드표현하다. 광범위한 파일 이름 목록을 통해 확장됩니다.“문서”의 정의l)는 현재 디렉터리에서 시작됩니다.

    # In a directory you created for testing purposes
    $ rm *; touch foo; ln -s foo link1; ln -s foo link2; ln -s foo link3
    $ set -x; ls -lR | grep l*
    + ls -lR
    + grep link1 link2 link3
    

    xtrace옵션(즉 set -x, 여러 쉘에서 사용 가능하며POSIX)는 파일 이름 확장(전역)의 효과를 표시하는 데 유용합니다. 즉, 문자열이 l*확장되어 link1 link2 link3의 내용에서 grep(심볼릭 링크 및 를 통해) 검색됩니다 . (link1foolink2link3grep검색할 패턴 뒤에 파일 이름 목록이 제공되면 표준 입력을 읽지 않습니다.

    혹시 당신이 가지고 있다면하나이름이 다음으로 시작하는 파일 l:

    # In a directory you created for testing purposes
    $ rm *; touch foo; ln -s foo link1; ln -s foo Link2; ln -s foo Link3
    $ set -x; ls -lR | grep l*
    + ls -lR
    + grep link1
    lrwxrwxrwx 1 user group 3 May  1 03:04 link1 -> foo
    

    그런 다음 grep표준 입력( 의 출력 ) 에서 여기 줄과 일치하는 문자열을 ls검색합니다 . ( 파일 이름이 제공되지 않거나 파일 이름 인수가 제공되면 link1표준 입력 읽기가 수행됩니다 ).grep-

    당신은해야인용하다쉘이 파일 이름 확장을 수행하지 못하도록 리터럴 문자열이 인수로 전달됩니다. 대안으로, 셸에서 지원하는 경우 set -f.

  3. 현재 디렉터리에 로 시작하는 파일 이름이 없으면 와일드카드 표현식은 변경되지 않고 l첫 번째 위치 인수로 전달됩니다. 그러면 이는 정규식으로 해석됩니다(기본값은grepgrepBRE 변형) 그 내용은 "모든 입력 줄에 대해 다음과 일치합니다.임의로 선택할 수 있는 l(어디서나)'는 다음 항목과 효과적으로 일치합니다.

    # In a directory you created for testing purposes
    $ rm *; touch foo
    $ ls -lR
    .:
    total 0
    -rw-r--r-- 1 user group 0 May  1 02:49 foo
    $ set -x; ls -lR | grep l*
    + ls -lR
    + grep 'l*'
    .:
    total 0
    -rw-r--r-- 1 user group 0 May  1 03:14 foo
    

    텍스트로 시작하는 문자열을 일치시키려면 l앵커 표현식이 필요합니다 grep '^l'.

답변3

아시다시피, 찾고 있는 명령은 다음과 같습니다.

ls -l | grep '^l'

따옴표가 반드시 필요한 것은 아닙니다.

디렉토리 트리가 아닌 현재 디렉토리를 원한다고 지정했기 때문에 -Ron 옵션을 제거하십시오 .ls

어느 쪽이든, 당신이 지적한 대답이 find아마도 더 나은 해결책일 것입니다.

관련 정보