ls -1 enumera mis elementos así:
foo.png
bar.png
foobar.png
...
Quiero que aparezca en la lista sin los siguientes .png:
foo
bar
foobar
...
(el directorio solo contiene .pngarchivos)
¿Alguien puede decirme cómo usar grepen este caso?
Propósito: Tengo un archivo de texto donde se enumeran todos los nombres sin la extensión. Quiero hacer un script que compare el archivo de texto con la carpeta para ver qué archivo falta.

.en ellos. Aunque la convención dice para nombrar sus archivos con.pngal final, no hay ninguna razón por qué no puedo tener un archivo PNG nombradofoo.zipomy.picture.20160518o simplementemypic.lsy canalizar la salida de ,lsyfindprincipalmente debido a la posibilidad de incurrir ennewline`tab char en el nombre del archivo. Si el nombre de archivo esThe new art of working on .png\NEWLINE files and other formatsmuchas de las soluciones propuestas creará problemas.Respuestas:
Solo necesita el shell para este trabajo.
POSIXY:
Con
zsh:fuente
printf;echo ${f%.png}Será suficiente.El
sedcomando elimina (es decir, reemplaza con la cadena vacía) cualquier cadena que se.pngencuentre al final de un nombre de archivo.Se
.escapa como\.para que se interpretesedcomo un.carácter literal en lugar de la expresión regular.(lo que significa que coincide con cualquier carácter). El$es el ancla de fin de línea, por lo que no coincide.pngen el medio de un nombre de archivo.fuente
sed 's/\.[^.]*$//'-1no es necesario, siendo el predeterminado aquí.-1debe especificarse. Es solo el valor predeterminado cuando la tubería está encendida, lo cual es una sorpresa oculta para algunos. Entonces hacerlo explícito ayuda a la comprensión. También hago esto en mis scripts para saber qué tipo de salida estoy esperando..png) antes de un carácter de nueva línea, borrará incluso eso.pngy no solo el último. Es mejor evitar canalizar y analizar la salida de ls, reserva sorpresas a menudo bien ocultas ... (algunas palabras y referencias más en la respuesta).Si solo quieres usar bash:
Debe buscar
grepcuando intente encontrar coincidencias, no para eliminar / sustituir esosedes más apropiado:Una vez que decida que necesita crear algunos subdirectorios para poner orden en sus archivos PNG, puede cambiarlo fácilmente a:
fuente
findhilo desedsolución puede presentar algunos problemas si encuentra un archivo con la tecla (.png) como parte del nombre y justo antes de un carácter de nueva línea. Es mejor evitar canalizar y analizar la salida defindols, reserva sorpresas a menudo bien escondidas ... (algunas palabras y referencias más en la respuesta).findcon algo comoechoen el último ejemplo. No está claro qué propósitofindsirve allí y los resultados dependen de la estructura del directorio (es decir, si tiene un directoriofiles.png)Yo iría por
basename(asumiendo la implementación de GNU):fuente
-z(o--zero) de GNU basename para producir una salida separada por NUL (en lugar de nueva línea).Otra respuesta muy similar (me sorprende que esta variante en particular aún no haya aparecido) es:
-1opciónls, yalsque supone que si la salida estándar no es una terminal (es una tubería, en este caso).-nopción asedsignifica 'no imprimir la línea por defecto'/popción al final de la sustitución significa '... e imprima esta línea si se realizó una sustitución'.El efecto neto de eso es imprimir solo aquellas líneas que terminan en
.png, con el.pngeliminado. Es decir, esto también atiende a la leve generalización de la pregunta del OP, donde el directorio no contiene solo.pngarchivos.La
sed -ntécnica a menudo es útil en casos en los que de otro modo podría usar grep + sed.fuente
.png) antes del carácter de nueva línea: en ese caso, imprimirá esa parte sin png, sin borrar solo la última parte. A menudo se sugiere evitar analizar (y canalizar) la salidalsporque los problemas pueden ocultarse justo donde no estás pensando ...findo, posiblemente mejor, use un lenguaje más poderoso queshpara administrarlos (el hecho de queshpueda hacer todo no significa que sea la mejor opción en cada caso). La carcasa está diseñada para usabilidad primero.ls, pero se trata de problemas futuros. A menudo creamos scripts que usaremos más tarde, cuando ya olvidaremos su límite ... (es humano, es habitual). I propuesto unfindejemplo (con-execy sin tubo), incluso si considero una mejor (debido shell puro) responde a la de uno cuonglm , sólida y posix compatible.locateomakesobre ellos.Puede usar solo comandos BASH para hacer eso (sin herramientas externas).
Esto es útil cuando no tiene / usr / bin y funciona bien para nombres de archivo como this.is.image.png y para todas las extensiones.
fuente
No es seguro analizar
lso canalizarfind[ 1 , 2 ]No es seguro analizar (y canalizar) la salida de
lsofind, principalmente porque es posible encontrar en los nombres de archivo caracteres no habituales como la nueva línea , la pestaña ... Aquí funcionará un ciclo de shell puro [ cuonglm ] .Incluso el
findcomando no conectado con la opción-execfuncionará:Actualizaciones / Notas : puede usar
find .para buscar incluso los archivos ocultos, ofind ./*.pngpara obtener solo los no ocultos. Confind *.png -exec ...usted puede tener un problema en el caso de que estuviera presente un archivo llamado.pngporque find lo obtendrá como una opción. Puede agregar-maxdepth 0para evitar descender en directorios nombrados comoDir_01.png, ofind ./*.png -prune -exec ...cuando maxdepth no está permitido (gracias Stéphane). Si desea evitar enumerar esos directorios, debe agregar la opción-type f(que también excluiría otros tipos de archivos no regulares). Eche un vistazo almanpara obtener un panorama más completo sobre todas las opciones disponibles, y recuerde verificar cuándo son compatibles con POSIX, para una mejor portabilidad.Algunas palabras mas
Puede suceder, por ejemplo, que al copiar el título de un documento y pegarlo en el nombre del archivo, una o más líneas nuevas terminen en el nombre del archivo. Podemos ser tan desafortunados que un título puede contener incluso la clave que tenemos que usar justo antes de una nueva línea:
Si desea probar, puede crear nombres de archivo como este con los comandos
El simple
/bin/ls *pngsaldrá en?lugar de los caracteres no imprimiblesEn todos los casos en los que se quiere canalizar la salida del
lsofindel comando siguiente tendrán ningún indicio de entender si la actual línea proviene de un nuevo nombre de archivo o si se sigue una nueva línea carácter en el precedente nombre de archivo . Un nombre desagradable en verdad, pero aún legal.Un ciclo de shell con un parámetro Parameter-Expansion,
${parameter%word}en la variante conprintfoechofuncionará [ cuonglm ], [ Anthon1 ] .Desde la página del manual de la expansión de parámetros de Shell [ 3 ]
fuente
findcomando son una variable de bit (por ejemplo, si hay un directorio llamadofiles.png)bash 4.3.11, dash 0.5.7-4, zsh (cuando sea necesario) 5.0.2. Siéntase libre de leer esta publicación que agrega algo más. Estoy de acuerdo con la nota de canalizar la salida defind, para esto sugerí expresamente-exec, y escribí en el título.:-).lsno hay ningún problema cuando la salida se canaliza o se redirige, pero como se menciona en wiki, puede que no funcione para todos. La mayoría solo insertará los?caracteres especiales en lugar de cuando la salida se envíe al terminal. es decir, hacerecho *.png | od -cyls *.png | od -c. El problema de la nueva línea no es un problemals, es un problema con cualquier comando que no termina nula en ambos lados de la tubería.printf "${f%.png}\n"Está Mal. El primer argumento es el formato, no debe usar datos variables allí. Incluso puede verse como una vulnerabilidad DoS (%1000000000s.pngpor ejemplo, intente con un archivo).find ./*.png -prune -exec...o tendría problemas con los nombres de archivo que comienzan con-(y los archivos de tipo directorio, tenga en cuenta que-maxdepthno es portátil)no fue suficiente?
o en general, esto
eliminará todas las extensiones
fuente
-1no es necesario, siendo el predeterminado aquí.lshace de todos modos sin esa opción cuando su salida no es una terminal, que es el caso aquí.Uso
rev:revinvierte todas las cadenas (líneas); cortas todo después del primer '.' y rev revierte el remanente.Si quieres
grep'alma':fuente
-1no es necesario, siendo el predeterminado aquí.My.2016.Summer.Vacation.pngcut -f 2-.pngy una nueva línea justo después ... Se sugiere evitar analizarlsporque le encanta ocultar bien las sorpresas ... :-)Si supiera que el directorio solo tiene archivos con .png como extensión, simplemente habría ejecutado:
ls | awk -F. '{print $1}'Esto devolverá el primer "campo" para cualquier cosa donde haya un nombre de archivo. Extensión.
Ejemplo:
fuente
.,Image.1.pnge incluso en los que no tienen nombres agradables , con caracteres especiales dentro. como el salto de línea o el que va a utilizar como (entrada) separador de registro enawk,RS. Se sugiere evitar analizar lalssalida porque le encanta ocultar el problema que surgirá cuando no lo espere. Puede leer más en las referencias 1 o 2 . Por cierto, es agradable la idea de usar awk ... Puse algunos ejemplos en una respuesta..en\.el interior de lased -e 's/\.png$//', pero por lo que se convierte en una respuesta acaba de escribir. :-( nota2 puede intentar usarawkcon algo comols | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'... pero siempre tendrá el problema de que awk no puede saber si la línea que está llegando sigue o no una nueva línea dentro del nombre del archivo. Intenté decir mejor en mi respuesta .de acuerdo con su comentario "Tengo un archivo de texto donde se enumeran todos los nombres sin la extensión. Quiero hacer un script PHP que compare el archivo de texto con la carpeta para ver qué archivo falta":
y al revés:
fuente
ls -l | sed 's/\.png$//'Es el método más preciso como lo destaca @roaima. Sin los escapados
\.pngarchivos con el nombrea_png.pngsería catalogado como:a_.fuente
ls -l, como lo hace, da los detalles del archivo, eso no es lo que el OP preguntó.Una línea de shell simple (ksh, bash o zsh; no dash):
Una función simple (desde Sin extensión):
O una función que elimina cualquier extensión dada (png por defecto):
Usar como:
Si la salida es un asterisco
*, no existe ningún archivo con esa extensión.fuente
Puede probar el siguiente feed awk la salida de ls su superator es el "." y como todos tus archivos tendrán nombre.png imprimes la primera columna:
ls | awk -F"." '{print $1}'fuente
Si tiene acceso a sed, esto es mejor ya que eliminará la última extensión de archivo, sin importar cuál sea (png, jpg, tiff, etc.)
fuente
this.is.a.dotty.txt. Intenta en sus/\.[^.]*$//lugar.