GNU find의 -printf 조건자를 사용할 때 바꾸는 방법은 무엇입니까?

GNU find의 -printf 조건자를 사용할 때 바꾸는 방법은 무엇입니까?

내 찾기 명령:

find * -type d -printf '%p\n'

결과는 다음과 같습니다.

Icons
Index
Index/Team
Index/Pricing
Index/WhyUs
Navbar
Share

나는 이 결과를 얻고 싶습니다:

Icons   components/Icons/Exports
Index   components/Index/Exports
IndexTeam   components/Index/Team/Exports
IndexPricing    components/Index/Pricing/Exports
IndexWhyUs  components/Index/WhyUs/Exports
Navbar  components/Navbar/Exports
Share   components/Share/Exports

find 명령을 다음과 같이 변경할 수 있습니다.

find * -type d -printf '%p\tcomponents/%p/Exports\n'

그러나 나는 다음과 같은 결과를 얻습니다.

Icons   components/Icons/Exports
Index   components/Index/Exports
Index/Team  components/Index/Team/Exports
Index/Pricing   components/Index/Pricing/Exports
Index/WhyUs components/Index/WhyUs/Exports
Navbar  components/Navbar/Exports
Share   components/Share/Exports

첫 번째 슬래시를 어떻게 바꿀 수 있습니까 %p?

답변1

-printf(GNU 구현별 조건자 ) 는 // ... 을 사용한 문자열 채우기/잘림 명령을 find제외하고는 다른 명령의 수정을 위한 어떠한 조항도 제공하지 않습니다 .%x%5p%-5p%.5p

하지만 여기서는 그럴 필요가 없습니다 find. 쉘 포함 zsh:

for f (**/*(N/)) printf '%s\tcomponents/%s/Exports\n' ${f:gs|/||} $f

또한 정렬된 목록을 제공하고 숨겨진 디렉터리를 제외하는 이점도 있습니다.

findGNU를 사용하여 출력을 사후 처리하는 경우에도 동일한 작업을 수행할 수 있습니다 . sort예를 들면 다음과 같습니다 .gawk

find . ! -name . -type d -print0 |
  sort -z |
  LC_ALL=C gawk -v RS='\0' '
    {
      name = path = substr($0, 3)
      gsub("/", "", name)
      print name"\tcomponents/"path"/Exports"
    }'

또는 숨겨진 항목을 제외합니다 zsh. 예를 들면 다음과 같습니다.

LC_ALL=C find . ! -name . '(' -name '.*' -prune -o -type d -print0 ')' |
  sort -z |
  LC_ALL=C gawk -v RS='\0' '
    {
      name = path = substr($0, 3)
      gsub("/", "", name)
      print name"\tcomponents/"path"/Exports"
    }'

또한 에서 find *셸은 *먼저 현재 디렉터리의 파일 목록을 확장하여 에 전달합니다 find. 이는 다음을 의미합니다.

  • 현재 디렉터리의 숨겨진 파일은 제외됩니다(그러나 해당 파일이 find발견된 하위 디렉터리에서는 제외됨).
  • -파일 이름이 조회 조건 자로 시작하면 혼동을 일으킬 수 있습니다.find
  • 최상위 레벨 목록은 정렬되지만(셸은 기본적으로 전역 확장을 정렬하기 때문에) 하위 레벨 목록은 정렬되지 않습니다(셸이 find정렬하지 않기 때문에).
  • 현재 디렉터리에 숨겨지지 않은 파일이 많으면 다음과 같은 문제가 발생할 수 있습니다.인수 목록이 너무 깁니다.find너무 큰 목록을 실행 하려고 시도하는 동안 오류가 발생했습니다.

find *로 바꾸면 거기에서 파일을 find .찾고 find위의 모든 문제를 피할 수 있습니다. 이는 또한 .(시작점)이 목록에 있다는 것을 의미하므로 ! -name .또는 -mindepth 1(GNU 확장자)를 사용하여 이를 제외해야 하며 대신 GNU를 사용할 수도 있지만 ./여기에서 제거한 출력에 접두사가 표시됩니다 .substr($0, 3)find-printf '%P\0'-print0

관련 정보