빈 문자열은 언제 현재 디렉터리를 나타냅니까?

빈 문자열은 언제 현재 디렉터리를 나타냅니까?

find다음과 같은 현재 디렉토리의 일부 파일을 수집하는 데 사용하는 스크립트에서

$ find . -name "*.h"
./foo.h

이제 접두사 foo.h없이 그냥 출력하고 싶습니다 . ./빈 문자열은 ""쉘 명령의 현재 디렉토리를 나타내는 것 같습니다. 그러나 이것은 다음을 제공합니다:

$ find "" -name "*.h"
find: ftsopen: No such file or directory

그래서 나는 틀렸다. 이제 내 질문은 언제/어떻게/어디서/.. "빈 문자열(?)"이 파일 이름이나 경로 이름이 필요한 명령의 현재 디렉터리를 의미합니까? 간결하고 계몽적인 설명이 있습니까?

부가적인 질문은 위의 찾기 항목을 문자열 조작 la ${parameter#word}또는 cut또는 sed? 없이 간단히 해결할 수 있는지 여부입니다.

답변1

오래 전 (에 7판, 32V, 4.2BSD, 4.3BSD), 시스템 호출 수준에서 현재 작업 디렉터리를 나타내는 길이가 0인 경로 이름입니다(조회에 사용되는 경우, 파일이나 디렉터리를 생성하거나 삭제하려고 할 때는 허용되지 않음). 존재하다 시스템 3, 길이가 0인 경로 이름을 사용하는 것은 모든 경우에 오류입니다.POSIX 표준경로 이름 확인에 대해 다음과 같은 말이 있습니다.

빈 경로 이름은 성공적으로 확인되지 않습니다.

답변2

당신은 그것을 사용할 수 있습니다 :

find * -name "*.h"

.로 시작하는 이름을 가진 현재 디렉토리의 파일은 .무시되고, .로 시작하는 이름을 가진 파일은 -옵션으로 해석되어 find혼란을 야기하므로 이는 find . ….

/파일 이름에 ""로 끝나는 문자열이 없습니다.힌트현재 디렉토리이지만 이것이 현재 디렉토리가 다음과 같다는 의미는 아닙니다.표현하다빈 문자열(인쇄할 때 동일하게 보일 수 있지만 이는 누락된 문자열과 동일하지 않을 수 있음)

답변3

일반적으로 빈 문자열은 쉘 명령이나 시스템 호출의 경우 현재 디렉토리를 나타내지 않습니다.일부 구형 시스템에서는 작동하지만 POSIX 호환 시스템에서는 작동하지 않습니다..

때로는 빈 문자열을 전달하고 프로그램에 디렉터리 이름이 필요한 경우 프로그램이 현재 디렉터리를 사용하는 것을 알 수 있습니다. 이는 의도적인 경우도 있고, 주어진 문자열이 슬래시로 시작하지 않을 때 현재 디렉터리에 대한 절대 경로를 앞에 추가하는 부작용으로 인한 경우도 있습니다.

당신에게 가장 좋은 것은 떠나는 것입니다 ./. 해를 끼치 지 않습니다.

파일 목록이 다음과 같은 경우

find . … | sed 's!^\./!!'

이로 인해 개행 문자가 포함된 일부 파일 이름이 손상될 수 있습니다. 이는 일반적으로 인간이 소비하는 데에는 문제가 되지 않으며, 의 출력은 find지정되지 않기 때문에 프로그램 소비에 적합하지 않습니다. 프로그램 사용에 적합한 것을 사용하는 경우 -print0아마도 접두사에 신경 쓰지 않을 것입니다 ./.

find * …대신 사용할 수 있지만 단점이 많으며 일반적으로 다음과 같은 경우에는 적합하지 않습니다 find . ….find *

  • .생략되어 있습니다.
  • 모든 도트 파일(이름이 또는 ..` 으로 시작하는 파일 .)은 생략됩니다.
  • 현재 디렉터리에 (또는 ...이라는 파일)로 시작하는 파일 이름이 있으면 -옵션이나 조건자로 해석됩니다.!(find

필터가 현재 디렉터리를 제외하는 경우 첫 번째 사항은 중요하지 않습니다. 두 번째 점의 경우 패턴을 사용하여 ..?* .[!.]* *현재 디렉터리의 모든 파일과 일치할 수 있지만 각 패턴이 하나 이상의 파일과 일치하는지 확인하고 일치하지 않으면 무시해야 합니다. 가능하지만 매우 번거롭습니다. 마지막 비트는 스토퍼입니다. 따라서 find *빠른 명령줄 사용에는 적합할 수 있지만 스크립트에서는 사용하지 마십시오.

또 다른 접근 방식은 쉘의 재귀적 글로빙 기능을 사용하는 것입니다.

printf '%s\n' **/*.h

shopt -s globstar이를 위해서는 bash 및 ksh93을 통한 활성화가 필요하며 set -o globstar기본 POSIX 셸(예: dash)에는 존재하지 않습니다. 도트 파일은 기본적으로 탐색되지 않습니다. 이를 포함하려면 먼저 shopt -s dotglobbash 또는 ksh93 FIGNORE='@(.|..)'에서 도트 파일을 무시하지 않도록 globbing을 활성화하세요. 또한 이 명령은 일치하는 항목이 없으면 패턴을 인쇄합니다. bash에서 실행하면 shopt -s nullglob빈 줄이 인쇄되고 ~(N)**/*.hksh에서 패턴이 사용됩니다.

zsh에서는 기본적으로 재귀 와일드카드가 활성화되어 있습니다. glob 한정자를 사용 D하여 도트 파일을 포함하고 N일치하는 항목이 없으면 빈 줄을 인쇄합니다(기본적으로 패턴이 파일과 일치하지 않으면 zsh는 오류를 발생시킵니다). printf위와 같이 사용 하거나

print -rl -- **/*.h(DN)

답변4

몇 가지 트릭을 사용하여 선행 없이 find 출력을 얻을 수 있습니다 ./.

  1. find의 -printf옵션을 사용하고 그냥 print 하도록 지시하세요 %f. 바라보다 man find:

    %f는 모든 선행 디렉토리 파일 이름을 제거합니다(마지막 요소만).

    예를 들어:

    find . -name "*.h" -printf "%f\n"
    
  2. 구문 분석 출력:

    find . -name "*.h" | sed 's#^./##'
    
  3. @Anthon의 트릭

    find * -name "*.h"
    

다른 질문의 경우 빈 문자열은 현재 디렉터리를 나타내지 않습니다. 단지 다양한 프로그램이 현재 디렉터리를 기본 디렉터리로 갖고 있기 때문에 인수 없이 실행하면 현재 디렉터리에서 실행될 뿐입니다.

관련 정보