Extrayendo el número del nombre del archivo

Extrayendo el número del nombre del archivo

Tengo un nombre de archivo siguiendo este modelo:

 1.raw_bank_details_211.trg
 2.raw_bank_details_222.trg

Necesito usar el cutcomando en Unix y cortar la cadena anterior para obtener 211 y 222de las cadenas y hacer eco del valor.

Ya usé grep grep -o -E '[0-9]+', necesito una alternativa a esto.

Respuesta1

Sería mejor que utilizaras una herramienta de procesamiento de texto estándar en lugar de una herramienta ingenua como cut.

A continuación se muestran algunas formas:


Con awk, obteniendo el penúltimo campo _o separado:.

awk -F '[_.]' '{print $(NF-1)}' file.txt

grepcon PCRE ( -P):

grep -Po '\d+(?=[^_]*$)' file.txt
  • -osolo recibe la porción igualada

  • \d+coincide con uno o más dígitos

  • La anticipación positiva de ancho cero, (?=[^_]*$)garantiza que no _haya ningún seguimiento hasta el final de la línea.


Con sed:

sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
  • .*_coincide con todo hasta el final_

  • ([[:digit:]]+)coincide con los dígitos requeridos y se coloca en el grupo capturado

  • .*coincide con el resto

  • En el reemplazo, solo \1se utiliza el grupo capturado, .


Con perlsu misma lógica a la sedde:

perl -pe 's/.*_(\d+).*/$1/' file.txt 

Si debe usar cut, hágalo en dos pasos, primero obtenga el _cuarto campo separado y luego separe .el primer campo:

cut -d_ -f4 file.txt | cut -d. -f1

Esto no se recomienda ya que requiere que los números de campo estén codificados.


Si fuera una cadena, lo haría usando la expansión de parámetros de Shell:

% str='1.raw_bank_details_211.trg'

% str=${str##*_} 

% echo "${str%%.*}"
211

Todavía puedes usar una whileconstrucción y tomar cada línea en una variable y hacer esto, pero eso sería lento para un archivo grande. También puede utilizar _.como alternativa IFSy obtener el campo codificado (como cut) si lo desea.


Ejemplo:

% cat file.txt                          
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg

% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222

% grep -Po '\d+(?=[^_]*$)' file.txt         
211
222

% sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
211
222

% perl -pe 's/.*_(\d+).*/$1/' file.txt 
211
222

% cut -d_ -f4 file.txt | cut -d. -f1
211
222

Respuesta2

cutes la herramienta equivocada para eso. Para manipular cadenas cortas, como nombres de archivos, utilice las funciones de manipulación de cadenas del shell siempre que sea posible. Todos los shells de tipo sh¹ (sh, dash, bash, ksh, zsh,…) tienen cierta manipulación básica de cadenas como parte de la sustitución de variables. Véase, por ejemplo, elmanual del tableroen “expansión de parámetros”. Puede eliminar el prefijo/sufijo más corto/largo que coincida con un patrón.

Quiere la última secuencia de dígitos en el nombre del archivo, entonces:

  1. Determine el sufijo no numérico eliminando todo hasta el último dígito.
  2. Elimina ese sufijo.
  3. Quite todo hasta el último no dígito.
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"

¹ Excepto algunos shells Bourne anteriores a POSIX, pero no te importan.

información relacionada