일반적으로 나는 Unix 명령과 파이프에 더 창의적이지만 오늘은 그렇지 않습니다.
그래서 내가 가진 것은 이것입니다:
collage.jpg
DCIM001.jpg
DCIM002.jpg
아니면 이거:
001.jpg
002.jpg
boston-collage.jpg
아니면 가끔
panama-collage.jpg
DCIM001.jpg
DCIM002.jpg
이제 이 명령을 사용하면 이미지가 올바르게 정렬됩니다.
find "Image Folder" -print0 | sort -z | tar cv --no-recursion --null -T -
하지만 *collage.*가 있는 파일을 정렬 결과의 첫 번째 파일로 수정하여 해당 목록에서 만든 tar 아카이브에 먼저 추가하고 싶습니다. 어떤 아이디어가 있나요?
답변1
최종 목표가 파일을 원하는 순서대로 아카이브에 넣는 것이라면 간단한 해결책은 먼저 정렬하려는 파일로 아카이브를 만든 다음 마지막으로 정렬된 파일을 기존 아카이브에 추가하는 것입니다. 물론 이는 두 개 이상의 정렬된 세그먼트로 일반화될 수 있습니다. 이를 위해서는 아카이브 파일을 생성해야 하며 파이프라인의 아카이브에 추가할 수 없습니다.
tar cf foo.tar /images/*collage.*
find /images ! -name '*collage.*' -print0 | sort -z | tar rf foo.tar --null -T -
기본 유틸리티를 사용하여 사용자 정의 정렬을 수행하려는 경우 가능한 한 가지 방법은 항목이 속한 그룹을 나타내는 행에 접두사를 추가하는 것입니다. 그룹을 정렬하려는 순서대로 접두사 레이블을 정렬한 다음 접두사를 제거합니다.
find /images -print0 |
sed -z -e 's/.*collage\./1&/' -e 't' -e 's/^/2/' |
sort -z |
sed -z 's/^.//' |
tar …
또 다른 접근 방식은 사용자 정의 정렬을 표현할 수 있는 다른 언어(예: Perl, Python 또는 Ruby)로 정렬을 수행하는 것입니다. 이렇게 하면 해당 언어로 파일 이름 수집은 물론 아카이브 제작까지 할 수 있습니다. 다음은 정렬만 수행하는 Perl 예제입니다.
perl -e '$,=$\="\0"; print sort {
$a =~ /collage\./ ? $b =~ /collage\./ ? $a cmp $b : 1 :
$b =~ /collage\./ ? -1 : $a cmp $b
} @ARGV' /images/* | tar …
임시 다시 작성을 통한 정렬의 또 다른 예(Perl 커뮤니티에서는 "Schwarztian 변환"이라고 함):
perl -e '$,=$\="\0"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
@ARGV' /images/* | tar …
파일 이름의 결합된 길이가 명령줄 길이 제한을 초과하면 두 예제 모두 실패합니다. 이를 방지하려면 Perl이 파일 이름을 생성하도록 하십시오.
perl -e '$,=$\="\0"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
glob("/images/*")' /images/* | tar …
파일 이름을 재귀적으로 생성하거나 일부 필터링을 적용해야 하는 경우 다음을 사용할 수 있습니다.파일::찾기. Perl을 사용하여 아카이브를 생성하려면 다음을 사용할 수 있습니다.아카이브::타르.
답변2
내 제안은 다음과 같습니다. 임시 파일을 사용하세요.
tmpdir=$(mktemp)
find "Image Folder" -print0 > $tmpdir/temp
{ grep -z collage $tempdir/temp | sort -z;
grep -z -v collage $tempdir/tmp | sort -z; } | \
tar cv --no-recursion --null -T -
rm -rf $tmpdir
"이미지 폴더"에 넣지 않는 한 더 간단한 임시 파일을 사용할 수 있습니다.
find
이 솔루션의 기본 아이디어는 for 의 결과를 임시 파일에 저장하여 grep
두 개의 s를 실행할 수 있도록 grep
하고 각 결과를 별도로 정렬한 후 for 의 파이프라인에 결합하는 것입니다 tar
.