Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Linux (https://www.clubdelphi.com/foros/forumdisplay.php?f=25)
-   -   Como mezclar comandos unix en al terminal (https://www.clubdelphi.com/foros/showthread.php?t=80224)

winzo 10-09-2012 20:19:03

Como mezclar comandos unix en al terminal
 
Me explico un poco mas.

Me gustaría poder hacer en la terminal una mezcla de comandos, pongo algunos ejemplos.

-Hacer una búsqueda de archivos y copiar todos esos archivos a un directorio
-Borrar archivo que se encuentren en una búsqueda de directorios extraida de textos de un archivo.

Vaya, ya se imaginarán la amplia gama que se puede abarcar combinando comandos, pero no sé como hacerlo.

Solo conozco el hacer algún comando y usar después GREP.:rolleyes:

Les agradezco de antemano...

roman 10-09-2012 20:27:32

1. find
2. grep pipe

// Saludos

winzo 10-09-2012 20:28:49

Que respuesta tan escueta
 
Cita:

Empezado por roman (Mensaje 442665)
1. find
2. grep pipe

// Saludos

No he entendido nada

roman 10-09-2012 20:35:59

Bueno, la pregunta es demasiado genérica. Comprenderás que no puedes juntar de la misma manera cualesquiera comandos que se te ocurran. Ahora (aunque la sintaxis completa no la recuerdo) en cuanto a los dos ejempos que pones:

1. El comando find tiene una opción que te permite ejecutar un otro comando sobre cada uno de los resultados.
2. El operador | (pipe) te permite enviar la salida de un comando a la entrada de otro comando. grep podría servirte para buscar en el texto de los archivos y concatenar su salida con un comando para borrarlos.

// Saludos

winzo 10-09-2012 20:42:43

Otro ejemplo
 
Cita:

Empezado por roman (Mensaje 442669)
Bueno, la pregunta es demasiado genérica. Comprenderás que no puedes juntar de la misma manera cualesquiera comandos que se te ocurran. Ahora (aunque la sintaxis completa no la recuerdo) en cuanto a los dos ejempos que pones:

1. El comando find tiene una opción que te permite ejecutar un otro comando sobre cada uno de los resultados.
2. El operador | (pipe) te permite enviar la salida de un comando a la entrada de otro comando. grep podría servirte para buscar en el texto de los archivos y concatenar su salida con un comando para borrarlos.

// Saludos

Y si lo que quisiera es copiar todos los archivos obtenidos en una búsqueda?

roman 10-09-2012 20:45:33

Por ejemplo:

Código:

$ find *.sql -exec cp {} foo \;
copia todos los archivos con extensión sql al directorio foo.

// Saludos

winzo 10-09-2012 20:46:51

-excec?
 
Cita:

Empezado por roman (Mensaje 442672)
Por ejemplo:

Código:

$ find *.sql -exec cp {} foo \;
copia todos los archivos con extensión sql al directorio foo.

// Saludos


Me que da la duda de que es "-exec {}"

roman 10-09-2012 20:48:46

¡A mi también! :D

Pero, según entiendo, se refiere a cada uno de los elementos encontrados por find, es decir, ejecuta el sigiente comando en cada término encontrado.

Par mayor información:

Código:

$ man find
// Saludos

mamcx 11-09-2012 05:45:45

En *teoria* los comandos de unix comparten la idea de que la entrada de uno es la salida del otro, desafortunadamente ya que operan principalmente sobre texto sin estructura algunas cosas salen mas complejas que otras, y sin ejemplos concretos es dificil meterse en la cabeza como se supone que opera todo.

Aqui un ejemplo, con relacion a una noticia reciente, con la linea de *razonamiento* y los resultados:

http://intrepidusgroup.com/insight/2...king-udid-src/


Y asi entiendes que con:

Cita:

cat data | cut -c 2-7 | sort | uniq -c | sort -n -r | head
Puedes ver los textos repetidos entre 2-7 caracteres, ordenados y los resultados principales (como un LIMIT):

Cita:

11 4daa64abd
10 d1f575954
10 aa5c7aedb
8 12e6ec97e
7 f661c1396
7 4225e2a59
6 91a83b0e3
6 480074431
Creo que es el primer ejemplo de esto que entiendo, de forma intuitiva ;)

P.D: Por otro lado, prefiero usar python para resolver cosas como esas, me parece mas facil de operar -porque puedo usar estructuras de datos, en vez de a)texto sin estructura b) switches de comandos de dificil recordacion y no siempre estandares. Muchos otros usan perl o algo similar.

Casimiro Notevi 11-09-2012 10:51:09

Con la siguiente instrucción podemos ver los 10 comandos más utilizados y cuantas veces lo hemos usado.

Cita:

antonio@linox:~$ history|awk '{print $2}'|awk 'BEGIN {FS="|"} {print $1}'|sort|uniq -c|sort -rn|head -10
137 sudo
88 ll
59 cd
28 locate
21 top
18 sh
17 exit
16 wget
16 more
12 gedit
antonio@linox:~$
La verdad es que muy intuitivo no es.

roman 11-09-2012 16:32:46

Ciertamente puede usarse python, pero los administradores de servidores normalmente usarán directamente los comandos o scripts del shell. Python o Perl son para tareas más complejas.

// Saludos

roman 11-09-2012 18:51:52

Cita:

Empezado por Casimiro Notevi (Mensaje 442766)
La verdad es que muy intuitivo no es.

Bueno, aquí estás usando el lenguaje AWK incrustado en el comando y ciertamente AWK es todo menos intuitivo. De todas formas, con práctica, el uso de comandos se torna intuitivo.

Veamos cómo obtener los diez comandos más usados:

1. El comando history nos da los últimos comandos ejecutados. La salida de history se ve similar a esto:

Código:

  460  find .
  461  find . -exec rm
  462  find . -exec rm {}
  463  find . -exec rm {} \;
  464  find *.sql -exec rm {} \;
  465  ls
  466  cd ..
  467  cp *sql foo/
  468  ls
  469  cp foo.bmp foo/
  470  cd foo
  471  ls
  472  find *.sql -exec rm {} \;

Cada comando precedido por un número y hay varios espacios separando los números de los comandos.

2. Lo primero es tener delimitadores bien definidos. Para ello podemos comprimir los espacios separadores en uno sólo con el comando tr (transalate) aplicado a la salida de history:

Código:

history|tr -s ' '
La opción s es de squeeze. La salida se ve similar pero ya sólo hay un espacio separando los términos:

Código:

460 find .
 461 find . -exec rm
 462 find . -exec rm {}
 463 find . -exec rm {} \;
 464 find *.sql -exec rm {} \;
 465 ls
 466 cd ..
 467 cp *sql foo/
 468 ls
 469 cp foo.bmp foo/
 470 cd foo
 471 ls
 472 find *.sql -exec rm {} \;
 473 ls
 474 touch asql
 475 ls
 476 find *.sql -exec rm {} \;
 477 rm .
 478 ls
 479 rm *
 480 ls
 481 cd ..
 482 find *.sql -exec cp {} foo\ \;
 483 find *.sql -exec cp {} foo \;
 484 cd foo

3. El comando cut sirve para tomar partes de una cadena, pueden ser letras o columnas delimitadas. En este caso, nuestras columnas están delimitadas por un espacio y nos interesa la tercera (hay un espacio al principio):

Código:

history|tr -s ' '|cut -d ' ' -f3
-d indica el delimitador que por defecto es el tabulador y -f el número de columna deseada. La salida queda así:

Código:

find
find
find
find
find
ls
cd
cp
ls
cp
cd
ls
find
ls
touch
ls
find
rm
ls
rm
ls
cd
find
find
cd

Ya tenemos aislados los comandos.

4. O casi, porque podríamos tener concatenaciones anteriores:

Código:

ls|grep sql
Si sólo nos interesa el comando base tendremos que repetir el comando cut ahora con el pipe de separador:

Código:

history|tr -s ' '|cut -d ' ' -f3|cut -d '|' -f1
5. El comando uniq sirve para trabajar líneas repetidas y su opción -c las cuenta. Pero como sólo cuenta líneas repetidas adyacentes, primero hay que ordenarlas con el comando sort:

Código:

history|tr -s ' '|cut -d ' ' -f3|cut -d '|' -f1|sort|uniq -c
uniq antepone el número de ocurrencias:

Código:

      4 cd
      2 cp
      9 find
      7 ls
      2 rm
      1 touch

6. Ahora usamos sort nuevamente para ordenarlas por número de ocurrencias pues es la primera columna de la salida:

Código:

history|tr -s ' '|cut -d ' ' -f3|cut -d '|' -f1|sort|uniq -c|sort
7. Finalmente, tomamos las últimas (tail) 10:

Código:

history|tr -s ' '|cut -d ' ' -f3|cut -d '|' -f1|sort|uniq -c|sort|tail -10
8. Como detalle, podemos eliminar el mismo comando history del listado usando grep antes de contar:

history|tr -s ' '|cut -d ' ' -f3|cut -d '|' -f1|grep -v history|sort|uniq -c|sort|tail -10



Como se ve, cada comando se aplica naturalmente. Con práctica se vuelve intuitivo y muy potente para, por ejemplo, revisar bitácoras.

// Saludos

Casimiro Notevi 11-09-2012 19:17:56

#:-)#

Sí, "más o menos" lo sabía, aunque no tan detalladamente. ¿Lo conoces tan bien como para no tener que consultar lo que hace cada comando?

roman 11-09-2012 19:21:21

Ja, ja, no :o

Cuando digo que con la práctica se vuelve intuitivo no me refiero a mi sino a gente que he visto trabajar así. Pero el desglose (ese sí es mío) deja ver que en efecto es así.

Por otra parte, aunque un administrador, muchos comandos los sabe al derecho y alrevés, es lógico que no está excento de consultar la referencia. Lo mismo nosotros con delphi, la ayuda no la echamos al cajón del olvido :)

// Saludos

roman 11-09-2012 19:24:51

Lo que si es un misterio para mi, es ¿para qué quiero saber los diez comandos que más uso? :D

// Saludos

Casimiro Notevi 11-09-2012 19:30:37

Muy importante no es :rolleyes:

mamcx 11-09-2012 22:34:52

A modo comparativo, lo mismo, con python

NOTA: Para hacer llamadas a lineas de comandos, se usa subprocess, o os.popen, pero dio la casualidad que "history" es un comando desactivado sino se esta en modo interactivo, osea, es dificil de hacerle programacion. Normalmente uno haria:

Código PHP:

import os

resultado
=os.popen("ls").read()

print 
resultado 

Pero "history" es un maldito que no se deja asi. Una fregada del bash.

Asi que uno puede hacer:

Código PHP:

history resultado.txt 

Para tener el resultado en un archivo de texto. Desde ahi, entrar a python y:

1. Cargar el archivo, separado por lineas, en una estructura de lista:

Código PHP:

lineas open('resultado.txt').readlines() 

Una lista se lee asi:

http://effbot.org/zone/python-list.htm

2. Ahora le mochamos los numeros y dejamos los comandos. La solucion "simple" es partir cada linea y construir otra lista

Le hago trim a cada linea, parto con split (por defecto parte por 1 espacio), y cojo el segundo resultado (split devuelve otra lista asi: ['1','comando'])

Código PHP:

comandos = [linea.strip().split()[1] for linea in lineas

Código:

> print comandos[:5]
>>> ['ls', 'chflags', 'ls', 'python', 'easy_install']

3. Ahora viene la parte de "conocer realmente python" o tambien llamada " usar google". Como se cuantas veces cada item de la lista se repite? El algoritmo es facil de armar, pero la idea que llevo es hacer lo mismo, con comandos de pocas lineas. Pero con python, las baterias estan incluidas!:

collections.Counter me devuelve un diccionario, con llave= comando, valor = cuantas veces se repite

Código PHP:

import collections

rank
=collections.Counter(comandos

Y ahora como ordenarlo. Otro algoritmo facil a punta de ciclos FOR, pero que carajos, python tiene baterias incluidas, asi que googleando:

Código PHP:

from operator import itemgetter

ordenado 
sorted(rank.items(), key=itemgetter(1)) 

Esto me ordena usando una funcion de ordenacion, enviada como parametro de comparacion (un truco de programacion funcional, creo que ya es mas conocido). Esto me ordena de menor a mayor. Como obtengo los mas usados? Lo puede reversar, y sacar los primeros (tail)

Código PHP:

ordenado.reverse()

print 
ordenado[:10]
>> [(
'hg'988),
 (
'cd'709),
 (
'sudo'648),
 (
'st'430),
 (
'ls'354),
 (
'ci'275),
 (
'python'223),
 (
'push'212),
 (
'clear;'188),
 (
'heroku'182)] 


Lo que me gusta de hacerlo con python, a pesar de que igual hay que aprender del lenguaje y las librerias (y que ciertas cosas obviamente sale mejor o mas rapido directamente por comandos establecidos) es que puedo interactuar con los datos. En cualquier momento, doy un print, saco los 10 primeros de la lista, le hago un for, etc... es mucho mas practico en muchos casos.

La otra razon, es que python se puede resumir en: Maneja lista, maneja diccionario. Practicamente todo devuelve listas y diccionarios. Es mucho mas intuitivo que operar siempre con cadenas y switches, y mas facil de operar. Es algo que se vuelve obvio cuando se entra a linea de comandos interactivo de python y se hacen las llamadas a las funciones: listas, diccionarios, todo el tiempo. Es muy practico!

Casimiro Notevi 11-09-2012 22:50:37

Está muy bien, aunque hay que tener python, crear el programita, etc.
No le quito el mérito, pero la "gracia" de la línea de comando unix/linux es esa, que de "un tirón", interactivamente, puedes hacerlo.

roman 11-09-2012 22:51:40

Sí, realmente se ve bien. Yo creo que cada uno tiene su ámbito. El uso de comandos del shell es más para administradores en sus tareas del día a día en que no van a hacer un script por cada tarea que requieran al momento. La solución que describes es más agradable para nosotros los programadores :)

// Saludos

mamcx 11-09-2012 22:58:10

Claro, como programador me gusta mas. Ademas, es aprender un solo ambiente (python) que ademas me sirve para otras cosas, vs varios (bash, windows) que solo sirve pa administrar....

Y no hay que crear el programa, todo se puede desde la linea interactiva...


La franja horaria es GMT +2. Ahora son las 22:58:22.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi