lunes, 17 de agosto de 2015

Comando SED en Linux

Qué es sed

SED (Stream EDitor) es un editor de flujos y ficheros de forma no interactiva. Permite modificar el contenido de las diferentes líneas de un fichero en base a una serie de comandos o un fichero de comandos (-f fichero_comandos).

Sed recibe por stdin (o vía fichero) una serie de líneas para manipular, y aplica a cada una de ellas los comandos que le especifiquemos a todas ellas, a un rango de las mismas, o a las que cumplan alguna condición..

Su sintaxis es de la forma:
sed [opciones] ´[comandos]´ archivos-de-entrada.

Algunas de sus opciones son:

i Insertar línea antes de la línea actual.
a Insertar línea después de la línea actual.
c Cambiar línea actual.
d Borrar línea actual.
p Imprimir línea actual en salida estándar.
s Sustituir cadena en línea actual.
r archivo Añadir contenido de “archivo” a la línea actual.
w archivo Escribir salida a un archivo.
! Aplicar instrucción a las líneas no seleccionadas por la condición.

q Finalizar procesamiento del archivo.

Por ejemplo:

  Sustituir apariciones de cadena1 por cadena2 en todo el fichero:
  # sed 's/cadena1/cadena2/g' fichero > fichero2

  Sustituir apariciones de cadena1 por cadena2 en las líneas 1 a 10:
  # comando | sed '1,10 s/cadena1/cadena2/g'
  
  Eliminar las líneas 2 a 7 del fichero
  # sed '2,7 d' fichero > fichero2
  
  Buscar un determinado patrón en un fichero:
  # sed -e '/cadena/ !d' fichero
  
  Buscar AAA o BBB o CCC en la misma línea:
  # sed '/AAA/!d; /BBB/!d; /CCC/!d' fichero

  Buscar AAA y BBB y CCC:
  # sed '/AAA.*BBB.*CCC/!d' fichero
  
  Buscar AAA o BBB o CCC (en diferentes líneas, o grep -E):
  # sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
  # gsed '/AAA\|BBB\|CCC/!d'

Formato de uso


El formato básico de uso de sed es:
  # sed [-ns] '[direccion] instruccion argumentos'

Donde:

[direccion] es opcional, siendo un número de línea (N), rango de números de línea (N,M) o búsqueda de regexp (/cadena/) indicando el ámbito de actuación de las instrucciones. Si no se especifica [direccion], se actúa sobre todas las líneas del flujo.
Instruccion puede ser:
i = Insertar línea antes de la línea actual.
a = Insertar línea después de la línea actual.
c = Cambiar línea actual.
d = Borrar línea actual.
p = Imprimir línea actual en stdout.
s = Sustituir cadena en línea actual.
r fichero = Añadir contenido de "fichero" a la línea actual.
w fichero = Escribir salida a un fichero.
! = Aplicar instrucción a las líneas no seleccionadas por la condición.
q = Finalizar procesamiento del fichero.
-n: No mostrar por stdout las líneas que están siendo procesadas.

-s: Tratar todos los ficheros entrantes como flujos separados.

Ejemplos de sustitución

Reemplazar cadenas:
  # sed 's/^Host solaris8/Host solaris9/g' fichero > fichero2

Reemplazar cadenas sólo en las lineas que contentan una cadena:
  # sed '/cadena_a_buscar/ s/vieja/nueva/g' fichero > fichero2

Reemplazar cadenas sólo en en determinadas líneas:
  # sed '5,6 s/vieja/nueva/g' fichero > fichero2

Reemplazar multiples cadenas (A o B):
  # sed 's/cadenasrc1\|cadenasrc2/cadena_nueva/g'

Sustituir líneas completas (c) que cumplan o no un patrón:
  # echo -e "linea 1\nlinea 2" | sed '/1/ cPrueba'
    Prueba
    linea 2
  # echo -e "linea X 1\nlinea 2" | sed '/1/ !cPrueba'
    linea 1
    Prueba


Ejemplos de Inserción

Insertar en una linea especifica en este caso la linea 41 del archivo fichero.txt
sed -i '41a Texto_a_ingresar' fichero.txt


Insertar 3 espacios en blanco al principio de cada línea:
  # sed 's/^/   /' fichero

Añadir una línea antes o despues del final de un fichero ($=última línea):
  # sed -e '$i Prueba' fichero > fichero2
  # sed -e '$a Prueba' fichero > fichero2

Insertar una linea en blanco antes de cada linea que cumpla una regex:
  # sed '/cadena/{x;p;x;}' fichero

Insertar una linea en blanco detras de cada linea que cumpla una regex:
  # sed '/cadena/G' fichero

Insertar una linea en blanco antes y despues de cada linea que cumpla una regex:
  # sed '/cadena/{x;p;x;G;}' fichero
  
Insertar una línea en blanco cada 5 líneas:
  # sed 'n;n;n;n;G;' fichero
  
Insertar número de línea antes de cada línea:
  # sed = filename | sed 'N;s/\n/\t/' fichero
  
Insertar número de línea, pero sólo si no está en blanco:
  # sed '/./=' fichero | sed '/./N; s/\n/ /'

Si una línea acaba en \ (backslash) unirla con la siguiente:
  # sed -e :a -e '/\\$/N; s/\\\n//; ta' fichero

Ejemplos de Selección/Visualización

  Ver las primeras 10 líneas de un fichero:
  # sed 10q
  
Ver las últimas 10 líneas de un fichero:
  # sed -e :a -e '$q;N;11,$D;ba'
  
Ver un rango concreto de líneas de un fichero:
  # cat -n fich2 | sed -n '2,3 p'
    2    linea 2
    3    linea 3
  (Con cat -n, el comando cat agrega el número de línea).
  (Con sed -n, no se imprime nada por pantalla, salvo 2,3p).

Ver un rango concreto de líneas de varios ficheros:
  # sed '2,3 p' *
    linea 2 fichero 1
    linea 3 fichero 1
    linea 2 fichero 2
    linea 3 fichero 2
  (-s = no tratar como flujo sino como ficheros separados)

Sólo mostrar la primera linea de un fichero:
  # sed -n '1p' fichero > fichero2.txt

No mostrar la primera linea de un fichero:
  # sed '1d' fichero > fichero2.txt

Mostrar la primera/ultima línea de un fichero:
  # sed -n '1p' fichero
  # sed -n '$p' fichero

Imprimir las líneas que no hagan match con una regexp (grep -v):
  # sed '/regexp/!d' fichero
  # sed -n '/regexp/p' fichero

Mostrar la línea que sigue inmediatamente a una regexp:
  # sed -n '/regexp/{n;p;}' fichero

Mostrar desde una expresión regular hasta el final de fichero:
  # sed -n '/regexp/,$p' fichero
  
Imprimir líneas de 60 caracteres o más:
  # sed -n '/^.\{60\}/p' fichero
  
Imprimir líneas de 60 caracteres o menos:
  # sed -n '/^.\{65\}/!p' fichero
  # sed '/^.\{65\}/d' fichero
  
Ejemplos de Borrado

Eliminar un rango concreto de líneas de un fichero:
  # sed '2,4 d' fichero > fichero2.txt

Eliminar todas las líneas de un fichero excepto un rango:
  # sed '2,4 !d' fichero > fichero2.txt
  
Eliminar la última línea de un fichero
  # sed '$d' fichero

Eliminar desde una línea concreta hasta el final del fichero:
  # sed '2,$d' fichero > fichero2.txt

Eliminar las líneas que contentan una cadena:
  # sed '/cadena/ d' fichero > fichero2.txt
  # sed '/^cadena/ d' fichero > fichero2.txt
  # sed '/^cadena$/ d' fichero > fichero2.txt

Eliminar líneas en blanco (variación del anterior):
  # comando | sed '/^$/ d'
  # sed '/^$/d' fichero > fichero2.txt

Eliminar múltiples líneas en blanco consecutivas dejando sólo 1:
  # sed '/./,/^$/!d' fichero

Añadir una línea después de cada línea:
  # echo -e "linea 1\nlinea 2" | sed 'aPrueba'
    linea 1
    Prueba
    linea 2
    Prueba

Eliminar espacios al principio de línea:
  # sed 's/^ *//g' fichero

Eliminar todos los espacios que haya al final de cada línea:
  # sed 's/ *$//' fichero

Eliminar espacios sobrantes a principio y final de línea, o ambos:
  # sed 's/^[ \t]*//' fichero
  # sed 's/[ \t]*$//' fichero
  # sed 's/^[ \t]*//;s/[ \t]*$//' fichero

Eliminar tags HTML:
  # sed -e :a -e 's/<[^>]*>//g;/</N;//ba' fichero
  
Borrar líneas duplicadas no consecutivas de un fichero:
  # sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P' fichero

Eliminar líneas en blanco y comentarios bash:
  # comando | sed '/^$/ d'
  # sed '/^$/d; / *#/d' fichero > fichero2.txt

Uso de salida selectiva

Salir a nuestra voluntad antes de acabar el fichero:
  # sed -e '/uno/ s/uno/1/' -e '/salir/ q' fichero > fichero2.txt
  # sed 10q fichero
  # sed q fichero

Equivalencia de -e con ";":
  # sed -e '/AAA/b' -e '/BBB/b' -e 'd'  ==  sed '/AAA/b;/BBB/b;d'

Usar 'q' apropiadamente reduce tiempo de procesamiento:
  # sed -n '10,20p' fichero
  # sed -n '21q;10,20p' fichero  -> Más rápido que el anterior.
  
Conversión de CRLF de DOS a formato UNIX (LF):
  # sed 's/.$//' fichero
  
Conversión de LF de UNIX a formato DOS (CRLF):
  # sed 's/$'"/`echo \\\r`/" fichero
  
Obtener el Subject de un correo, pero sin cadena "Subject: ":
  # sed '/^Subject: */!d; s///;q' fichero
  
Imprimir párrafo (cadenas entre 2 líneas en blanco) si contiene XXX:
  # sed -e '/./{H;$!d;}' -e 'x;/XXX/!d;' fichero

Imprimir párrafo si contiene (1) XXX y ZZZ o bien (2) XXX o ZZZ :
  # sed -e '/./{H;$!d;}' -e 'x;/XXX/!d;/ZZZ/!d'
  # sed -e '/./{H;$!d;}' -e 'x;/XXX/b' -e '/ZZZ/b' -e d


Insertar espacios en blancos en un archivo con SED, expresiones regulares

Insertar espacios en un fichero

Añadir una línea en blanco después de cada frase (forzada por un retorno de carro):
sed G fichero.txt

Añadir una línea en blanco después de cada frase (forzada por un retorno de carro), sin tener en cuenta las líneas en blanco existentes:
sed '/^$/d;G' fichero.txt

Añadir dos líneas en blanco después de cada frase (forzada por un retorno de carro),
sed 'G;G' fichero.txt

Insertar una línea en blanco antes de cada línea que cumpla con una “/ocurrencia/” (la ”ocurrencia” puede ser una expresión regular):
sed '/Fin/{x;p;x}' fichero.txt

Insertar una línea en blanco antes y después de cada línea que cumpla con una /ocurrencia/ (la ”ocurrencia” puede ser una expresión regular):
sed '/Inicio/G' fichero.txt

Insertar una línea en blanco antes y después de cada línea que cumpla con una /ocurrencia/ (la ”ocurrencia” puede ser una expresión regular):
sed '/Stream EDitor/{x;p;x;G}' fichero.txt

miércoles, 12 de agosto de 2015

Eliminar determinado texto en un archivo con SED, expresiones regulares

Sintaxis

sed '{[/]<n>|<cadena>|<regex>[/]}d' <nombre_ fichero>
sed '{[/]<direccion1>[,<direccion2>][/]d' <nombre_fichero
/.../ = delimitadores
n = el número de línea
cadena = la cadena contenida en la línea
regex = expresión regular correspondiente a la ocurrencia buscada
direccion = la dirección de una línea (número u ocurrencia)
d = delete (borrar)

Ejemplos

Eliminación de la 3ra línea 

sed '3d' mi_fichero.txt


Eliminación de la línea conteniendo la cadena "awk" 

sed '/awk/d' mi_fichero.txt


Eliminación de la última línea 

sed '$d' mi_fichero.txt


Eliminación de todas las líneas vacías 

sed '/^$/d' mi_fichero.txt
sed '/./!d' mi_fichero.txt


Eliminación de la línea conteniendo una expresión regular 
(aquí se elimina la línea conteniendo caracteres numéricos (al menos 1 cifra) situados al final de la línea) 

sed '/[0-9/][0-9]*$/d' mi_fichero.txt


Eliminación del intervalo comprendido entre las líneas 7 y 9 

sed '7,9d' mi_fichero.txt


Lo mismo pero esta vez la dirección es reemplazada por una ocurrencia 

sed '/-Inicio/,/-Fin/d' mi_fichero.txt

Nota

Los ejemplos precedentes únicamente modifican la visualización del archivo (salida estándar 1 = la pantalla). 
Para realizar modificaciones permanentes, en las antiguas versiones (<4) utilizar un fichero temporal, para GNU sed utilizar el parámetro "-i[sufijo]" (--in-place[=sufijo]), como en el ejemplo siguiente: 

sed -i".bak" '3d' mi_fichero.txt


No mostrará el resultado en la salida estándar, y modificará el fichero original "mi_fichero.txt" eliminando la 3ra línea y creará un fichero de respaldo llamado "mi_fichero.txt.bak" 
---------------------------------------------------

Fichero a ser utilizado en los ejemplos (mi_fichero.txt): 

Introducción
Este es un ejemplo de fichero para familiarizarse con el filtro “sed”.

Presentación

-Inicio-
Sed es un editor de flujo (Stream EDitor), derivado del editor de texto “ed”, muy utilizado
en los sistemas Unix.
-Fin-

Uso

El comando más utilizado del filtro “sed” es sin dudas el comando de sustitución (s), que
permite reemplazar en cada línea la primera ocurrencia de una cadena1 por una cadena2.
Para una sustitución de todas las ocurrencias (encontradas) en cada línea hay que utilizar
el parámetro “g” (global).

Conclusión

El filtro “sed” es sin dudas uno de los comandos más utilizados en asociación con otros
comandos como “grep” o "awk" para la escritura de scripts shell.
El conocimiento y el dominio de expresiones regulares es un plus.

martes, 11 de agosto de 2015

Insertar determinado texto en un archivo con SED, expresiones regulares

En determinadas ocasiones necesitamos insertar en el final de un archivo un texto, para ello podemos usar echo:

echo "Texto al final del archivo" >> archivo.txt

Pero, ¿qué hacer si deseo insertar el texto en el inicio?

Con sed y los parámetros adecuados podemos hacer esto y más.

Por ejemplo, para insertar en el inicio de un archivo un texto sería:

sed -i '1i Aqui texto que ira en la primera linea' archivo.txt


sed -i '22i moises    ALL=(ALL:ALL) ALL' /etc/sudoers  
Mientras que para insertar en el final es:

sed -i '$a Aqui el texto que ira en la ultima linea' archivo.txt






O bien el echo de toda la vida:

echo "Aqui el texto que ira en la ultima linea" >> archivo.txt

Para sustituir una linea es:

sed -i '1 s|texto_actual|texto_nuevo|g' /ruta/archivo 

sed -i '1 s|samba|samba.proyec.net.ve|g' /etc/hostname

Bueno nada más que agregar, es un post bastante corto en realidad.

Espero le resulte de utilidad a alguien, saludos.

miércoles, 22 de julio de 2015

Configurar SSH por otro puerto diferente al puerto 22

SSH es sin lugar a dudas el pan de cada día de los que administramos redes. Pues necesitamos controlar, administrar remotamente otros ordenadores y/o servidores, y usando SSH podemos hacer esto … podemos hacer esto y mas

Sucede que SSH usa por defecto el puerto 22, por lo que todos los intentos de hacking a SSH siempre irán por defecto al puerto 22. Una medida básica de seguridad es simplemente NO usar SSH en este puerto, configuraremos  por ejemplo SSH para que escuche (trabaje) en el puerto 9122.

Lograr esto es sumamente simple.

1. Debemos obviamente tener SSH instalado en nuestro servidor (paquete openssh-server)

2. Editemos el archivo /etc/ssh/sshd_config

Para esto en una terminal (como root) ponemos:

    nano /etc/ssh/sshd_config

Ahí entre las primeras líneas vemos una que dice:

Port 22

Le cambiamos el 22 por otro número, que sería el nuevo puerto, en este ejemplo dijimos que usaríamos el 9122, por lo que la línea nos quedaría:

Port 9122

3. Ahora reiniciamos SSH para que lea la nueva configuración:

    /etc/init.d/ssh restart

Esto en caso que usen Debian, Ubuntu, SolusOS, Mint. Si usan Arch sería:

    /etc/rc.d/ssh restart

Y listo, ya tendrán SSH por otro puerto (9122 según el ejemplo que hemos usado acá)

Bueno creo que no hay nada más que agregar.

Cualquier duda que tengan, me dejan saber

Saludos

PD: Recuerden, todo esto tienen que hacerlo con privilegios administrativos… bien sea como root, o usando sudo.

martes, 21 de julio de 2015

Programando en Bash (I)

1.- ¿Qué es un “Script”?

Básicamente decimos que es un archivo que contiene código escrito en determinado lenguaje de programación que el sistema usa para determinada tarea. No es necesario que tenga una entrada externa ni interfaz gráfica, pero sí que provoque una salida de datos procesados (por más de que el usuario no los vea).

El lenguaje usado por Bash está definido por su propio intérprete y combina la sintaxis de otros Shells, como el Korn Shell (ksh) o el C Shell (csh). Muchos de los comandos que usualmente se usan en la consola también pueden usarse en los scripts, salvo aquellos que pertenecen estrictamente a una distribución en particular.
 2.- Estructura de un "Script"


Para empezar debemos contar con un editor de texto y ganas de programar. Los archivos que guardamos con extensión .sh podrán ser ejecutados (o interpretados) por la consola, siempre y cuando la primera línea sea la siguiente:
 
#!/bin/bash
 
Esto le dice al sistema que deberá usar la consola para ejecutar el archivo. Además, el carácter # permite escribir comentarios. Para crear el ejemplo más simple agregamos una línea más, vista en la siguiente texto:

#!/bin/bash
echo "Hello World"

El comando echo muestra un mensaje en pantalla, en este caso el típico “Hello world!”. Si lo guardamos y ejecutamos con la consola veremos el resultado.
 

3.- Comandos básicos

Los siguientes comandos son comunes y muy útiles para cualquier tipo de programa. Aclaramos que existen muchos más, pero por ahora cubriremos los siguientes.
Alias: permite que una cadena de palabras sea sustituida por una más corta, permitiendo la reducción del código.

#creamos un alias llamado per con la dirección de la #carpeta Descargas

alias per=’/home/usuario/Descargas’

#Cada vez que queramos usarlo solo debemos llamar a #la nueva palabra

per

#Para destruir ese alias, usamos unalias

unalias per

 


break: permite salir inmediatamente de un ciclo for, while, until o select (más adelante estudiaremos detalladamente los ciclos)

 #Creamos un ciclo que asignará los números del 1 al 5 #por cada “vuelta de ciclo”

for contador in 1 2 3 4 5

do

#Imprimimos el actual valor de la variable #contador, el cual es analizado por el carácter $

echo “$contador”

#Si el valor de contador es igual a 3

if [$contador –eq 3]

then

#El break sale del ciclo for

break

fi

done


continue: similar al break, excepto que ignora la actual vuelta de ciclo y pasa a la siguiente.

#Creamos un ciclo que asignará los números del 1 al 5 #por cada “vuelta de ciclo”

for contador in 1 2 3 4 5

do

#Si el valor de contador es igual a 3

if [$contador –eq 3]

then

#Continue impide que se analize el resto del ciclo #actual saltando a la siguiente vuelta, o sea que el #valor 3 no se imprimirá.

continue

fi

echo “$contador”

done


declare: declara variables y les asigna valores, al igual que typeset (funcionan de la misma manera). Podemos combinarla con algunas opciones: -i declara números enteros; -r para variables de solo lectura, a las cuales no se les podrá cambiar el valor; –a para matrices o “arrays”; -f para funciones; -x para variables que podrán ser “exportadas” fuera del ambiente del script propio.

declare –i num=12

declare –x pi=3.14


help: muestra la ayuda de un comando concreto.
jobs: muestra los procesos en ejecución.

#Con –c mostramos el nombre de los comandos, con –p #el pid (id de proceso) de cada proceso.

jobs -cp


let: evalúa una expresión aritmética

let a=11

let a=a+5

#Finalmente imprimimos el valor de a que es 16

echo “11 + 5 = $a”


local: crea variables locales, las cuales deben ser usadas preferentemente en funciones del propio scripts para evitar errores. Puede usar las mismas funciones del comando declare.

local v1=”Esta es una variable local”

logout: permite salir del inicio de sesión de un Shell completamente; útil para los casos donde trabajemos con más de una ventana de Shell, en los cuales el comando exit solo permitirá finalizar una ventana a la vez.

printf: permite imprimir un dato y darle formato. Cuenta con muchas opciones, así que mencionaremos algunas.

# %f imprime como número flotante, n para nueva #línea

printf “%fn” 5

5.000000

# &d permite pasar números decimales como argumentos

printf “Hay %d pedidos valuados en %d dólares.n” 20 500

Hay 20 pedidos valuados en 500 dólares.


read: lee una línea de standard input (módulo usado en la carga de datos por medio del teclado por ejemplo). Podemos pasar opciones como: -t para dar un tiempo límite de lectura; -a para que cada palabra sea asignada a una posición del array aname; -d para usar un delimitador que se escribirá al final de la línea; entre otros.

echo “Ingresá tu nombre y presioná ENTER”

#Leemos la variable nombre

read nombre

echo “Tu nombre es $nombre”

type:
describe un comando y su comportamiento. Puede ser útil para averiguar las definiciones de datos de cada comando.

type –a ‘[’

#type nos dice que [ es un comando builtin del Shell

[ is a Shell builtin

# -a permite encontrar los directorios que contienen #un ejecutable con el nombre escrito.

[ is /usr/bin/[


ulimit: limita el acceso y uso de ciertos recursos del sistema a los procesos, ideal para programas que permiten hacer cambios administrativos o que están orientados a distintos tipos de usuarios. Al establecer un límite escribimos un número que representa los kilobytes del límite.

#Vemos nuestros límites actuales

ulimit –a

# -f permite limitar a los usuarios a que no puedan #crear archivos de mayor tamaño que 512000 Kb (500 #Mb)

ulimit –f 512000

# -v limita la memoria virtual del proceso.

ulimit –v 512000



wait: espera a que se realice determinado proceso o trabajo para continuar.
#El script espera a que se realice el proceso de pid #2585
wait 2585
Otros comandos útiles que podemos agregar a los scripts están representados por símbolos.
!!: ejecuta nuevamente el último comando
!wer: ejecuta el último comando que comenzaba con la expresión “wer”.
‘==’, ‘!=’, ‘>’, ‘< ‘, ‘>=’, y ‘< =': operadores relacionales.
|: el operador OR usado generalmente para unir dos expresiones regulares.
: comando de escape que permite formatear las expresiones. Por ejemplo: a para una alerta de sonido, n para nueva línea, b para el retroceso, etc.

miércoles, 1 de julio de 2015

Crear base de datos en posgres


a) Entra con usuario Postgres
# su postgres

b) Entra a Postgres
$ psql -U postgres 

c) Crea la base de dato en posgres
postgres=# CREATE DATABASE sgcst_canaima WITH OWNER=postgres ENCODING='UTF8'; 

d) Verificamos la bd exista
postgres=# \l

e) Salimos de postgres
postgres=# \l