해결책

해결책

배경:현재 일부 폴더와 해당 내용에서 압축된 타르볼을 생성하는 아카이브 스크립트를 작성 중입니다. 아카이브의 압축을 풀거나 소스를 압축하지 않고도 gzip으로 압축된 아카이브를 소스와 동기화할 수 있어야 합니다. 이를 위해 추구되는 해결책은 의 ls -l출력을 의 출력과 동기화하는 것 입니다 tar -ztvf.

두 명령 모두 비슷한 출력을 반환하지만 약간의 차이가 있습니다. 대부분의 차이점은 정규식이나 cut. 쉽게 해결할 수 없는 한 가지 문제는 최대 깊이에서 쿼리 디렉터리에 상대적인 파일 경로를 나열하는 것입니다.

이 문제를 극복하기 위해 저는 다음을 사용하여 각 파일을 찾아 find가져왔습니다.ls

find Webcam -exec ls -lR --time-style="+%Y-%m-%d %H:%M" {} \; | cut -f1,3- -d" " | sed "s/ /\//2" | sed "s/ \+/ /g"

이러한 파이프의 대부분은 형식 지정용이며 find Webcam -exec ls -lR {} \;문제의 부품이며 Webcam테스트 폴더입니다. 이 명령의 출력은 다음과 같습니다.

-rw-r--r-- debian/debian 162406 2014-04-12 13:42 2014-04-12-134210.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 2015-03-15-193905.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 2015-04-29-202242.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 2015-08-02-134230.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 2015-08-27-230306.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 Webcam/2015-08-02-134230.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 Webcam/2015-04-29-202242.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 Webcam/2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 Webcam/2015-03-15-193905.jpg
-rw-r--r-- debian/debian 162406 2014-04-12 13:42 Webcam/2014-04-12-134210.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 Webcam/2015-08-27-230306.jpg

이제 출력은 다음과 같습니다 tar -ztvf.

-rw-r--r-- debian/debian 162406 2014-04-12 13:42 Webcam/2014-04-12-134210.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 Webcam/2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 Webcam/2015-03-15-193905.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 Webcam/2015-04-29-202242.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 Webcam/2015-08-02-134230.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 Webcam/2015-08-27-230306.jpg

명백한 결함은 ls발견된 각 항목이 두 번 나열된다는 것입니다. 한 번은 필요한 경로가 있고 다른 한 번은 경로가 없습니다. 각 항목을 두 번 나열하는 방법을 "수정"합니까 ls?

이 오류의 성격(예: 뒤에서 무슨 일이 일어나고 있는지)에 대한 추가 통찰력과 전체 보관 문제에 대한 보다 실용적인 접근 방법을 참고로 환영합니다. 하지만 이제는 이것이 도전이라고 생각하고 해결하고 싶기 때문에 주요 초점은 한계에 맞춰져야 합니다 ls.

답변1

문제는 find Webcam도 디렉토리를 찾고 ls Webcam이를 실행하면 거기에 있는 모든 파일이 나열된다는 것입니다. 디렉토리가 아닌 파일만 나열하려면 다음을 입력하십시오.

-type f

답변2

귀하의 질문은 ls -lR모든 파일(파일을 표시함)과 각 디렉토리(디렉토리의 내용을 표시함)에 대해 실행됩니다. 디렉터리 계층 구조가 단순하지 않지만 하위 디렉터리를 포함하는 경우 마치 하위 디렉터리를 다시 탐색하는 것처럼 콘텐츠가 더 자주 표시됩니다 -R. ls대신 find다음과 같이 호출해야 합니다.

  1. find . -type f -exec ls -l {}, 파일만 표시됩니다.
  2. find . -exec ls -dl {}, 파일과 디렉터리가 표시됩니다.

답변3

이 문제의 근본 원인은 매우 짧습니다( .예: 1점).

이해 (디렉토리 제외)는 .from find과 동일합니다 .find .man find

경로가 지정되지 않으면 현재 디렉터리가 사용됩니다.

그리고 실행하면 find .생성된 목록에 포인트가 나타납니다
(간단하게 유지하려면 이름이 다른 파일 4개를 사용하면 됩니다).

$ find                        ### Works the same with or without the dot.
.
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

그런 다음 이 목록을 (재귀적으로) 제공합니다 ls -R.
단 한 번의 클릭으로 모든 파일을 복제할 수 있습니다.

$ ls -1R .         ### The 1 will make the list 1 column.
.:
Webcam
2014-04-12-134210.jpg
2014-08-09-163849.jpg

./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

따라서 모든 파일이 두 번 나타나는 것은 당연합니다(한 번은 점으로, 한 번은 조회에서).

$ find -exec ls -1R {} \;
.:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

해결책

점을 삭제합니다( 사용 \( ! -name . -prune \) -a).

find로 찾은 파일 목록에서 포인트를 제거합니다.

$ find . \( ! -name . -prune \) -a -print
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam

그런 다음 재귀를 사용할 수 있습니다 ls -R.

$  find . \( ! -name . -prune \) -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

재귀적 ls를 피하세요(더 간단하지만 필수 ls -d).

재귀를 사용하지 않고 ( 디렉터리로 확장하지 않는 옵션 ls -R도 있음 ) 트리를 탐색하여 모든 파일을 찾아보겠습니다.-dfind

$ find . ! -path . -exec ls -1d {} \;  
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg    

보관소

물론 아카이브를 특정 용도로 사용하려면
디렉터리 이름이 필요하지 않고 전체 경로 파일 이름만 있으면 됩니다.

$ find . ! -path ./ -type f -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

(포인트가 아님) 에 대해 find dir.

경로를 사용하는 경우 디렉터리 깊이가 1보다 크면 문제는 동일합니다.

이는 문제를 일으키지 않습니다.

$ find Webcam -exec ls -1R {} \;
Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
Webcam/2015-04-29-202242.jpg
Webcam/2015-08-27-230306.jpg

그러나 깊이를 1씩 늘리면(cd ..) 다음이 수행됩니다.

$ cd ..
$  find jpg -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/2014-08-09-163849.jpg
jpg/2014-04-12-134210.jpg
jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg

다음은 트리거되지 않습니다.

$  find jpg \( ! -path ./jpg -prune \) -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

나는 두 가지 재귀 도구를 사용하는 것이매우 현명하지 못한.

더 간단한 구조로 변경하세요. 예를 들어 find jpg -ls다음과 같이 셸에서 제공하는 목록 솔루션을 사용해 보세요 echo **.

$ (shopt -s globstar nullglob; printf '%s\n' jpg/**/*)
jpg/2014-04-12-134210.jpg
jpg/2014-08-09-163849.jpg
jpg/Webcam
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg

관련 정보