Obtener el último campo usando awk substr


Tengo un requisito simple como sigue,
Estoy obteniendo los nombres de archivo con el directorio absoluto.
Por ejemplo /home/parent/child/filename
Mi requisito es cortar el nombre del archivo de esto.
Lo que he intentado es:

awk -F "/" '{print $5}' input

Que funciona perfectamente.
Pero aquí estoy codificando duro $5 que puede diferir si mi entrada tiene la estructura de la siguiente manera:

/home/parent/child1/child2/filename

Así que debe ser dinámico sin codificación dura. Aquí está la lógica:
Siempre tome el último campo que será el nombre del archivo (Por lo que necesita para comprobar desde atrás).

¿Puede alguien ayudarme con la función awk substr o cualquier otra función ?

Author: Chris Koknat, 2013-07-29

8 answers

Use el hecho de que awk divide las líneas en los campos en función de un separador de campos, que puede definir. Por lo tanto, definiendo el separador de campos a / puede decir:

awk -F "/" '{print $NF}' input

Como NF se refiere al número de campos del registro actual, imprimir $NF significa imprimir el último.

Así que dado un archivo como este:

/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename

Esta sería la salida:

$ awk -F"/" '{print $NF}' file
filename
filename
filename
 145
Author: fedorqui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-20 13:50:00

En este caso es mejor usar basename en lugar de awk:

 $ basename /home/parent/child1/child2/filename
 filename
 23
Author: piokuc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-29 10:42:08

Otra opción es utilizar bash sustitución de parámetros .

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename
 5
Author: devnull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-29 12:04:58

Si está abierto a una solución Perl, aquí una similar a la solución awk de fedorqui:

perl -F/ -lane 'print $F[-1]' input

-F/ especifica / como separador de campos
$F[-1] es el último elemento de la matriz @F autosplit

 5
Author: Chris Koknat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-01 19:51:40

Sé que estoy como 3 años tarde en esto, pero.... debe considerar la expansión de parámetros, está incorporada y es más rápida.

Si su entrada está en un var, digamos, var var1, simplemente haga ${var1##*/}. Mira abajo

$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename
 3
Author: Adriano_epifas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-10 03:38:21

Debería ser un comentario a la respuesta basename pero no tengo suficiente punto.

Si no utiliza comillas dobles, basename no funcionará con la ruta donde hay un carácter de espacio:

$ basename /home/foo/bar foo/bar.png
bar

Ok con comillas " "

$ basename "/home/foo/bar foo/bar.png"
bar.png

Ejemplo de Archivo

$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3

$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3
 2
Author: Pierre-Damien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-22 09:01:17

Como 5 años tarde, lo sé, gracias por todas las propuestas, solía hacer esto de la siguiente manera:

$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename

Me alegra notar que hay mejores modales

 1
Author: Nicko Glayre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-24 16:03:40

También puedes usar:

    sed -n 's/.*\/\([^\/]\{1,\}\)$/\1/p'

O

    sed -n 's/.*\/\([^\/]*\)$/\1/p'
 -1
Author: SARATH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-31 01:53:42