나는 사용하고있다nsxivFreeBSD에서 JPEG 및 PNG 이미지를 봅니다. 하지만 FreeBSD의 nsxiv에서 이미지를 보기 위해 수정 시간별로 이미지를 정렬하고 필터링하는 방법을 찾을 수 없습니다. GNU coreutils 및 GNU findutils를 사용하는 Linux에서는 다음 명령을 사용하여 2023년 10월 1일 이후에 수정된 이미지를 수정 시간별로 정렬하여 볼 수 있습니다.
find . -maxdepth 1 -type f \
\( -iregex '.+\.jpe?g$' -o -iregex '.+\.png$' \) \
-newermt 2023-10-01 \
-exec ls -t --zero -- {} + | \
nsxiv -0 -
공백, 개행 및 기타 특이한 문자가 포함된 파일 이름을 처리하는 동일한 명령을 FreeBSD에서 찾을 수 없습니다. 문제는 FreeBSD에 있습니다.ls
FreeBSD의 또 다른 문제는 --zero
NUL로 구분된 파일 이름을 출력하는 옵션이 없습니다 .nsxiv
find
-printf0
에 전달할 수 있는 항목이 없습니다 sort -z
. 이미지를 수정 시간별로 정렬 및 필터링하고 FreeBSD의 nsxiv에서 보는 방법은 무엇입니까?
저는 Linux와 FreeBSD에서 /bin/sh
(대시)를 사용하고 있습니다 /bin/sh
.
답변1
일반 FreeBSD 시스템에서 실행하는 것이 중요하다면 find/xargs/cut/stat에 대한 또 다른 대답이 있습니다. 다른 유틸리티를 설치할 수 있는 경우 zsh를 사용하는 더 명확한 답변도 있습니다.
하지만 GNUism과 Linux에 익숙하다면 GNU가 설치되어 있으면 FreeBSD에서도 편하게 생활하기가 쉽습니다.도구 찾기.
pkg install findutils
마찬가지로 사람들은 BSD ls, grep, make, sed 및 awk에 갇혀 있습니다. 그러나 GNU 대응 제품도 쉽게 사용할 수 있습니다.놀,그누그렙,지메이크,게사르그리고멍하니. 가는거야모두그리고 나서핵심 도구
이들은 모두 시스템의 BSD 버전과 공존할 수 있습니다. 그런 다음 일반적으로 명령 앞에 GNU 버전의 "g" gnuls
( , gfind
, 및 ) gxargs
를 붙입니다.gmake
gsed
gawk
좋아하는 Gnu 변형 앞에 접두사를 붙이는 것이 싫다면 "FreeBSD에서 GNU grep을 기본값으로 만드는 방법은 무엇입니까?"
BSD 변형에 익숙하다면 Linux에서도 사용할 수 있습니다. 바라보다bsdutils
답변2
정렬을 수행하려면 xargs를 올바르게 전달해야 합니다.
find . -maxdepth 1 -type f \
\( -iregex '.+\.jpe?g$' -o -iregex '.+\.png$' \) \
-newermt 2023-10-01 \
-print0 \
\|
xargs -0 \
stat -n -f '%Y %N\0' \
\|
sort -z \
\|
cut -z -d ' ' -f2- \
\|
nsxiv -0 -
우리는 튜플이 있는 언어에서 일반적으로 볼 수 있는 "장식-정렬-장식 취소" 기술을 사용합니다. 여기서는 정렬 키(통계의 epoch 이후 초 %Y
)를 값(파일 이름)과 공백으로 구분해야 합니다 . 그런 다음 cut
돌아 왔습니다. 조금 당황 스럽습니다!
답변3
다음을 수행할 수 있습니다.
zsh +o caseglob -c '
autoload after
print -rN -- *.(jp(e|)g|png)(.e[after 2023-10-01]om)' | nsxiv -0 -
이식성과 안정성을 고려하면 perl
아마도 최선의 방법은 다음과 같습니다.
perl -MTime::HiRes=lstat -MPOSIX -MFile::Glob=:nocase -e '
$start = mktime(0,0,0, 1,10-1,2023-1900); # 2023-10-01
for (<*.{jpg,jpeg,png}>) {
push @files, [$_, $s[9]] if @s = lstat and -f _ and $s[9] >= $start;
}
print "$_->[0]\0" for sort {$b->[1] <=> $a->[1]} @files
' | nsxiv -0 -
귀하의-exec ls -t --zero -- {} +
파일 목록이 너무 커서 여러 번 find
호출해야 하는 경우 ls
파일을 수정 시간별로 제대로 정렬할 수 없습니다.
답변4
FreeBSD에서 작동하는 솔루션을 찾았습니다 /bin/sh
. FreeBSD 13.2에서 시도해 보았습니다. 선행 및 후행 공백을 포함하여 백슬래시와 공백(공백, 탭 및 줄 바꿈)이 포함된 파일 이름을 올바르게 처리하는 것으로 보입니다.
find . -maxdepth 1 -type f \
\( -iregex '.\{1,\}\.jpe\{0,1\}g$' -o -iregex '.\{1,\}\.png$' \) \
-newermt 2023-10-01 \
-exec ls -l -B -D%s {} + \
| cut -w -f6- | sort -r | cut -f2- \
| while read -r line; do
printf '%b\0' "$line"
done \
| nsxiv -0 -
작동 방식:
ls -l -B -D%s
-B
인쇄할 수 없는 문자를 8진수 표기법으로 표시합니다. 이는 개행 문자와 탭이 포함된 파일 이름을 처리하는 데 중요합니다.-D%s
형식 파일 수정 시간(에포크 이후의 초 수)입니다. 수정 시간별로 정렬하는 데 유용합니다.
cut -w -f6-
ls -l ...
: 파일 수정 시간과 파일 이름이 포함된 열을 제외하고 출력에서 모든 열을 제거합니다 .-w
연속된 공백은 구분 기호로 간주되어야 합니다.sort -r
: 수정 시간을 기준으로 가장 최근 것부터 오래된 것 순으로 파일을 정렬합니다.cut -f2-
: 파일 수정 시간 열을 제거하고 (줄 바꿈으로 구분된) 파일 이름만 유지합니다.- 마지막 부분: 개행으로 구분된 파일 이름을 하나씩 읽고
printf
형식%b
문자열을 사용하여 파일 이름의 8진수 표기법을 다시 실제 문자(예: 개행 및 탭 포함)로 변환합니다. NULL 문자(\0
)를 사용하여 파일 이름을 구분하고 NULL로 구분된 파일 이름을nsxiv -0 -
.
추가 참고 사항:
cut -w -f6- | sort -r | cut -f2-
ls
대신 사용할 수 없는 옵션입니다-t
. 사용자 "Stéphane Chazelas"는 이 페이지의 다른 답변에 다음과 같이 썼습니다.find ... -exec ls -t ... -- {} +
파일 목록이 너무 커서 여러 번find
호출해야 하는 경우ls
[ ]는 수정 시간별로 파일을 제대로 정렬할 수 없습니다.find ... \( -iregex '.\{1,\}\.jpe\{0,1\}g$' -o -iregex '.\{1,\}\.png$' \)
이는 확장 정규식을 사용하여 단순화할 수 있습니다. 예를 들어find -E ... -iregex '.+\.(jpe?g|png)$'
.- 소유자나 그룹 이름에 공백 문자가 있는 특별한 경우에는 이름 대신 사용자 ID와 그룹 ID가 출력되도록 옵션
-n
을 추가해야 할 수도 있습니다.ls
ls