¿Cómo anclar ciertos files cuando se usa orderar?

Normalmente soy más creativo con los commands y las tuberías de Unix, pero no hoy.

Entonces lo que tengo es esto:

collage.jpg DCIM001.jpg DCIM002.jpg 

o esto:

 001.jpg 002.jpg boston-collage.jpg 

o algunas veces

 panama-collage.jpg DCIM001.jpg DCIM002.jpg 

Así que ahora uso este command, que ordera las imágenes correctamente.

 find "Image Folder" -print0 | sort -z | tar cv --no-recursion --null -T - 

Pero me gustaría arreglar los files con * collage. * Como los primeros files de los resultados de sorting para agregarlos primero al file tar que estoy creando fuera de esa list. ¿Alguna idea?

Si el objective final es colocar los files en el file en el order deseado, entonces una solución simple es crear un file con los files para orderar primero, luego agregue los files para orderar el último al file existente. Por supuesto, esto se puede generalizar a más de dos segmentos de sorting. Esto requiere crear un file de almacenamiento, no se puede agregar a un file en una canalización.

 tar cf foo.tar /images/*collage.* find /images ! -name '*collage.*' -print0 | sort -z | tar rf foo.tar --null -T - 

Si desea realizar una sorting personalizada con solo las utilidades básicas, un método posible es agregar un prefijo a la línea que indica de qué grupo forma parte el elemento. Haga arreglos para que las tags de prefijo se clasifiquen en el order en que desea orderar los grupos, y luego quite esos prefijos.

 find /images -print0 | sed -z -e 's/.*collage\./1&/' -e 't' -e 's/^/2/' | sort -z | sed -z 's/^.//' | tar … 

Otro enfoque sería hacer la sorting en otro idioma, como Perl, Python o Ruby, donde se puede express una orderación personalizada. Si haces eso, podrías hacer la recostackción del nombre de file e incluso la producción del file en ese idioma. Aquí hay un ejemplo de Perl que solo hace la sorting:

 perl -e '$,=$\="\0"; print sort { $a =~ /collage\./ ? $b =~ /collage\./ ? $a cmp $b : 1 : $b =~ /collage\./ ? -1 : $a cmp $b } @ARGV' /images/* | tar … 

Y otro ejemplo que hace la sorting a través de una reescritura temporal (se llama "Transformación de Schwarztian" en la comunidad de Perl):

 perl -e '$,=$\="\0"; print map {substr($_,1)} sort map {$_ = (/collage\./ ? "1" : "2") . $_} @ARGV' /images/* | tar … 

Ambos ejemplos fallarán si la longitud combinada de los nombres de file excede el límite de longitud de línea de command. Para evitar eso, deje que Perl genere los nombres de los files.

 perl -e '$,=$\="\0"; print map {substr($_,1)} sort map {$_ = (/collage\./ ? "1" : "2") . $_} glob("/images/*")' /images/* | tar … 

Si necesita generar nombres de files recursivamente o aplicar algún tipo de filtrado, puede usar File :: Find . Si desea generar el file en Perl, puede usar Archive :: Tar .

Aquí está mi sugerencia, usando un file temporal:

 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 

Podría usar algo más simple para el file temporal, siempre y cuando no lo coloque dentro de "Carpeta de image".

La idea básica detrás de esta solución es save los resultados de find en un file temporal para que podamos ejecutar dos grep s contra él, orderando cada resultado de grep individualmente antes de combinarlos en el pipe para tar .