dir
두 개의 일반 파일이 있습니다.
file1
예 abc\n
, file2
있습니다 def\n
. 아래와 같이 gzip을 사용하여 두 파일을 압축합니다.
#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz file2.gz
내용물을 긁어낸 후,
#find . -type f -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n
파일 생성 시간 순서대로 파일 내용을 가져오지 못해요. 예상되는 출력은 항상 이어야 합니다 abc\ndef\n
.
흥미로운 관찰: 실제 출력은 def\nabc\n
때때로abc\ndef\n
질문:
타임스탬프 순서(내림차순/증가)로 파일을 찾는 방법은 무엇입니까?
답변1
보고된 파일 순서는 find
사용자에게 불투명합니다. 디렉토리에 나타나는 순서일 수 있습니다. 일부 find
구현에서는 성능 향상을 위해 inode 번호 또는 기타 기준에 따라 순서를 변경합니다. 순서를 변경하는 유일한 방법은 -depth
조건자를 통해 find
처리/출력이 현재 있는 분기보다 먼저 나가도록 지시하는 것입니다.
대안으로 재귀 glob 함수를 find
사용할 수 있습니다 .zsh
zgrep whatever ./**/*.gz(D.Om)
Glob Om
한정자는 마지막 수정 시간을 기준으로 정렬됩니다(가장 오래된 것부터). 기본적으로 숨겨진 (점) 파일을 포함하여 일반 파일( 's 와 동일 ) .
에서만 작동합니다 .find
-type f
D
find
당신이 얻을 경우인수 목록이 너무 깁니다.오류가 발생했습니다. 다음을 사용할 수 있습니다 zargs
.
autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever
(또는 Ksh 스타일 프로세스 대체를 지원하는 셸) 및 최신 GNU 도구를 사용 bash
하면 다음과 같습니다.
xargs -r0a <(
export LC_ALL=C
find . -type f -name '*.gz' -printf '%T@\t%p\0' |
sort -zn | cut -zf2-) zgrep whatever
답변2
한 가지 옵션은 파일 경로와 함께 파일 타임스탬프를 출력하고 이를 기준으로 정렬한 다음 삭제하는 것입니다.
find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat
파일 이름에 잠재적으로 안전하지 않은 문자(예: 공백)가 포함될 수 있는 경우 간단히 바꾸십시오.
xargs zcat
그리고
xargs -d "\n" zcat
파일 이름에 개행 문자를 수용해야 하는 경우 @stéphane-chazelas의 답변에 자세히 설명된 대로 널 바이트를 사용하여 레코드를 종료할 수 있습니다(실제로는 거의 문제가 발생하지 않음).
답변3
안타깝게도 find 명령이 작동하는 방식에 따라 출력이 파일 연령에 따라 알파벳순 또는 시간순으로 정렬된다는 보장은 없습니다. 다음과 같이 시도해 볼 수 있습니다.
ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1