una - sacar lista de archivos linux
Extraiga el nombre base del archivo sin ruta y extensión en bash (9)
Aquí están los oneliners:
-
$(basename ${s%.*})
-
$(basename ${s} .${s##*.})
Necesitaba esto, lo mismo que pedían bongbang y w4etwetewtwet.
Esta pregunta ya tiene una respuesta aquí:
- Extraer nombre de archivo y extensión en Bash 35 respuestas
Dados nombres de archivos como estos:
/the/path/foo.txt
bar.txt
Yo espero conseguir:
foo
bar
¿Por qué esto no funciona?
#!/bin/bash
fullfile=$1
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname
¿Cuál es la forma correcta de hacerlo?
Aquí hay otra forma (más compleja) de obtener el nombre de archivo o la extensión, primero use el comando rev
para invertir la ruta del archivo, corte desde la primera .
y luego invierta la ruta del archivo de nuevo, así:
filename=`rev <<< "$1" | cut -d"." -f2- | rev`
fileext=`rev <<< "$1" | cut -d"." -f1 | rev`
El comando basename tiene dos invocaciones diferentes; en uno, usted especifica solo la ruta, en cuyo caso le da el último componente, mientras que en el otro también le da un sufijo que eliminará. Por lo tanto, puede simplificar su código de ejemplo utilizando la segunda invocación de nombre base. Además, tenga cuidado de citar correctamente las cosas:
fbname=$(basename "$1" .txt) echo "$fbname"
No tienes que llamar al comando de basename
externo. En su lugar, podrías usar los siguientes comandos:
$ s=/the/path/foo.txt
$ echo ${s##*/}
foo.txt
$ s=${s##*/}
$ echo ${s%.txt}
foo
$ echo ${s%.*}
foo
Tenga en cuenta que esta solución debería funcionar en todos los shells que cumplen con POSIX recientes ( posteriores a 2004 ) (por ejemplo, bash
, dash
, ksh
, etc.).
Fuente: Shell Command Language 2.6.2 Expansión de parámetros
Más sobre las manipulaciones de cadenas de bash: http://tldp.org/LDP/LG/issue18/bash.html
Si quieres jugar bien con las rutas de archivos de Windows (bajo Cygwin) también puedes probar esto:
fname=${fullfile##*[/|//]}
Esto tendrá en cuenta los separadores de barra invertida al usar BaSH en Windows.
Solo una alternativa que se me ocurrió para extraer una extensión, usando las publicaciones en este hilo con mi propia pequeña base de conocimientos que me era más familiar.
ext="$(rev <<< "$(cut -f "1" -d "." <<< "$(rev <<< "file.docx")")")"
Nota: Por favor avise sobre mi uso de citas; funcionó para mí, pero podría faltar algo en su uso apropiado (probablemente uso demasiados).
Una combinación de nombre base y corte funciona bien, incluso en caso de doble terminación como .tar.gz
:
fbname=$(basename "$fullfile" | cut -d. -f1)
Sería interesante si esta solución necesita menos poder aritmético que la expansión de parámetros de Bash.
Utilice el comando basename. Su página de manual está aquí: http://unixhelp.ed.ac.uk/CGI/man-cgi?basename
bash
puro, sin basename
, sin malabares variables. Establecer una cadena y echo
:
s=/the/path/foo.txt
echo ${s//+(*//|.*)}
Salida:
foo
Nota: la opción bash
extglob debe estar "activada" (en Ubuntu está " activada " por defecto), si no lo está, haz:
shopt -s extglob
Caminando a través de ${s//+(*//|.*)}
:
-
${s
- comienza con $ s . -
//
sustituir cada instancia del patrón. -
+(
coincide con uno o más de la lista de patrones entre paréntesis. -
*//
coincide con cualquier cosa antes de/
. (1er patrón) -
|
O. (separador de patrón). -
.*
coincide con cualquier cosa después.
. (2do patrón) -
)
Lista de patrones finales. -
}
expansión del parámetro final - ya que no hay/
(que precedería a un sustituto de cadena), se eliminan los patrones coincidentes.
Fondo relevante de man bash
:
- sustitución de patrones :
${parameter/pattern/string} Pattern substitution. The pattern is expanded to produce a pat‐ tern just as in pathname expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with #, it must match at the begin‐ ning of the expanded value of parameter. If pattern begins with %, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / fol‐ lowing pattern may be omitted. If parameter is @ or *, the sub‐ stitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.
- coincidencia extendida de patrones :
If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the fol‐ lowing sub-patterns: ?(pattern-list) Matches zero or one occurrence of the given patterns *(pattern-list) Matches zero or more occurrences of the given patterns +(pattern-list) Matches one or more occurrences of the given patterns @(pattern-list) Matches one of the given patterns !(pattern-list) Matches anything except one of the given patterns