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
한정자는 마지막 수정 시간을 기준으로 정렬합니다(가장 오래된 것부터). .
일반 파일 전용( find
's 와 동일 -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