2011-05-02 8 views
5

que estoy tratando de que mi script para ls todos los archivos de la forma "$ variable". *

el parámetro es siempre un archivo con la extensión .001 quiero encontrar todos los archivos con el mismo nombre pero diferente extensión, por ejemplo, $ file.002, file.003 etc .: por ejemplo

first="$1" 
others=${first%.001} 
ls $others"*" 

Mi problema es el archivo se llama file[success].mpg.001 y lo que se alimenta a ls es file[success].mpg* que me da ls: cannot access file[success].mpg*: No such file or directory porque ls necesidades a ver:

file\[success\].mpg* 

He estado tratando de todo, la única cosa que me di cuenta es ls alimentan el parámetro $ 1 funciona, pero no si se alimenta archivo $ después de lo que he hecho file = $ 1. Entonces, ¿cómo cambio la variable en un parámetro?

Respuesta

6

Usted podría utilizar bash 's printf comando para cambiar el formato de la cadena. Además no es necesario citar *:

#!/bin/bash 
first="$1" 
others=$(printf %q "${first%.001}") 
ls $others* 

printf %q cambia el formato de la cadena en un formato que se puede utilizar como entrada de comandos (con respecto a la página hombre bash 's).

edición con respecto a un comentario:
La solución anterior no funciona con espacios en blanco en los nombres de archivo. Para esos casos (como algunas otras respuestas ya mencionadas) que es mejor no utilizar printf pero para citar correctamente todas las variables:

#!/bin/bash 
first="$1" 
others="${first%.001}" 
ls -- "$others"* 
+0

¡muchas gracias! – geekmagii

+0

Me alegro de poder ayudarte. – bmk

+1

Esto funciona para archivos con corchetes en los nombres, pero no para otros caracteres impares como espacios. Por ejemplo, probé './findfiles1" test [success] .mpg.001 "', y analizó eso como dos nombres de archivo y tampoco encontré: 'ls: \ [success \]. Mpg *: No such file o directorio '' ls: prueba \: No existe tal archivo o directorio'. –

1

Uso encontrar su lugar ls:

$ ls weg.* 
ls: weg.*: No such file or directory 
$ find . -name weg.\* 
$ 
+1

[Por más de una razón] (http: // mywiki.wooledge.org/ParsingLs) – l0b0

+0

encontrar. -name file [success] .mpg * no encuentra nada. – geekmagii

+1

de la respuesta de l0b0, supongo que debería usar una forma diferente que ls – geekmagii

2

Usted no está demasiado lejos. Mi primer punto de referencia está cambiando la línea 3 a la siguiente:

ls -- "${others}".* 

Esto ampliará $others y permitir que el englobamiento suceda. Es responsabilidad de shells expandir el * a la lista de todos los nombres de archivo coincidentes. La lista de nombres de archivos se envía a ls. Suena como en la mayoría de los casos ls verá algo como esto:

file1.001 file1.002 file1.003 ... 

Pero, cuando no hay archivos están presentes, la cáscara pasa el pegote a ls y se verá asterisco:

file1.* 

Por lo tanto, su línea, ls $others"*" agrega un asterisco literal que verá.

A menos que tenga un nombre de archivo file1.* (con un asterisco literal), ls fallará.

Otra opción es utilizar nombre base:

first="$1" 
others=`basename -- "$first" .001` 
ls -- "${others}".* 

Usando basename le da la ventaja de que puede eliminar directorios, etc.

Sin embargo, como han señalado otros, dependiendo de lo que esté haciendo con la lista de archivos, find puede ser mejor.

EDITAR: El doble guión no funciona en todas las variantes * nix pero indica los comandos ls y basename que no siguen otros argumentos cli. Citar sus variables puede ser una buena práctica, pero prefiero la simplicidad de dejarlas a menos que los datos no sean de confianza. Conozca sus datos y cotice apropiadamente.

+0

Sus variables no están entre comillas, lo que causa problemas si los nombres de los archivos contienen espacios u otros caracteres "especiales". Use 'ls -" $ others "*' y 'basename -" $ first "' en su lugar. – Philipp

+0

@Philipp - Muy bien, editado. –

5

Usted debe citar la variable, no es el comodín:

ls -- "$others"* 

El doble guión se detiene la búsqueda de opciones para que este código debería funcionar incluso si others comienza con un guión.

Tenga en cuenta que ls es a menudo la solución incorrecta en las secuencias de comandos. Úselo solo si realmente desea imprimir la lista, p. en formato largo:

ls -l -- "$others"* 

Si desea imprimir sólo los nombres, no es necesario en absoluto ls:

echo "$others"* 

Lamentablemente no se puede utilizar con --echo. Sin embargo, si quieres una matriz con los nombres de archivo, utilice

filenames=("$others"*) 

Y en caso de que desee iterar sobre ellos, utilizar

for filename in "$others"* 
Cuestiones relacionadas