Invertir el orden de las líneas de un archivo en Linux

Si necesitamos procesar el contenido de un archivo, tomando sus líneas desde la última a la primera (por ejemplo en un archivo de log) podemos programar un script que las lea todas y luego aplique la acción en el orden requerido. Pero si pudiéramos hacerlo desde la consola sería mejor. Y se puede.

Simplemente utilizamos el comando tac (el inverso de cat) el cual concatena cada archivo que se pasa como argumento pero en el orden inverso, línea por línea desde el final del archivo.

Ejemplo:

tac original.log > invertido.log

crea el archivo invertido.log con las líneas en el orden opuesto al que poseen en original.log

 

Tip: No confudamos con tail, el cual imprime las últimas líneas de un archivo pero en el orden original.

Anuncios

Repetir el comando previo con ajustes en Linux

Si bien podemos utilizar la flecha hacia arriba del teclado para mostrar el comando ejecutado previamente en la consola, existe la posibilidad de usar el doble signo de admiración:

$ !!

Esta forma es más conveniente cuando queremos agregar algo antes o después del comando ejecutado.

Ejemplo 1:

$ chown www-data:www-data www
chown: cambiando el propietario de «www»: Operación no permitida

Queremos cambiar el dueño y grupo del directorio www, pero no tenemos permiso

$ sudo !!
sudo chown www-data:www-data www
[sudo] password for user:

Una vez que escribamos el password del usuario, la acción se habrá realizado.

Ejemplo 2:

$ crontab -l

Muestra todo el contenido del archivo crontab del usuario logueado en la consola

$ !! > crontab.txt

Generamos un archivo con todo el contenido de dicho crontab.

Reiniciar la conexión a Internet desde jDownloader

Si bien prefiero las descargas por Torrent o MagnetLink, hay contados casos donde tengo que utilizar jDownloader para organizar las descargas directas. Resulta útil poder configurarlo para que genere una reconexión automática, la cual nos brinde una IP diferente de nuestro proveedor de Internet y así poder continuar con la siguiente descarga desde el mismo servicio (sin esperas eternas).

  • Abrir jDownloader
  • Elegir la solapa Settings
  • Abrir el menú de la izquierda Modules -> Reconnection
  • Presionar el botón Select Router
    • Elegir el de marca y modelo más similar al nuestro. Se presenta el script asociado.
    • Si no existe ninguno, presionar Create Reconnection Script
      • Seguir los pasos para generar una reconexión en el router. La aplicación los irá registrando para así generar un script a medida.
  • Presionar el botón Fetch Router IP
    • Se completa el campo “Router’s IP”
    • Si no sucede, completar el campo manualmente.
  • Completar los campos User y Password con las credenciales para acceder a la administración web del router
  • Presionar el botón Change IP

Si todo funciona correctamente veremos que nos presenta la nueva IP y se ilumina la carita feliz.

En mi caso, poseo un módem router adsl TP-Link modelo TD-W8961ND y el script es el siguiente:

[[[HSRC]]]

  [[[STEP]]]
    [[[REQUEST]]]
    GET /Forms/tools_system_1 HTTP/1.1
    Host: %%%routerip%%%
    Authorization: Basic %%%basicauth%%%
    [[[/REQUEST]]]
  [[[/STEP]]]
  [[[STEP]]]
    [[[REQUEST]]]
    GET /progress.htm HTTP/1.1
    Host: %%%routerip%%%
    Authorization: Basic %%%basicauth%%%
    [[[/REQUEST]]]
  [[[/STEP]]]
[[[/HSRC]]]

Pasar al siguiente mail luego de mover el actual en Gmail

Por defecto, cuando estamos viendo un mail en Gmail y hacemos alguna de las siguientes acciones:

  • moverlo a otra etiqueta
  • archivarlo
  • eliminarlo
  • marcarlo como spam

volvemos automáticamente al listado de correos donde nos encontrábamos previamente.

Por lo general, cuando leo el correo me gusta ir organizándolo al mismo tiempo y este comportamiento me obliga cada vez a seleccionar el primer mail del listado para verlo.

Por suerte existe uno de los servicios de Lab de Gmail que trata justo esta temática: Avance automático, el cual según se indica “Muestra de forma automática la conversación siguiente, en lugar de volver a Recibidos, tras eliminar, archivar o silenciar una conversación”. Lo bueno es que no se limita solo a Recibidos, como indica el mensaje.

Para activarlo contamos con estos pasos:

  • Acceder a la cuenta de Gmail
  • Desde el icono del engranaje, elegir “Configuración”
  • Seleccionar la solapa “Labs”
  • Buscar la función “Avance automático
  • Marcar la opción “Habilitar” asociada a la misma

Una vez hecho esto, desde la solapa “General”, podremos configurar en el apartado “Avance automático” si queremos que vaya a la conversación más nueva o la más antigua. Yo tengo seleccionado “la más antigua”, dado que las tengo ordenadas por fecha descendente (desde la más reciente) y casi siempre accedo a la primera.

Exportar todo el contenido de una MediaWiki en HTML

Necesitaba poder tener todas las páginas de una MediaWiki en formato HTML en un directorio, con sus imágenes, para poder usarlo como un respaldo navegable del estado actual de esa wiki. Encontré la extensión DumpHTML y la implementé tal como se indica:

  1. Descargar el archivo tar.gz de la extensión para la versión de MediaWiki instalada
  2. Descomprimir su contenido en el directorio extensions

Exportar el contenido

La acción se realiza desde la línea de comandos, ejecutando:

php <MEDIAWIKI_PATH>/extensions/DumpHTML/dumpHTML.php -d <DESTINATION_DIR> --image-snapshot

lo que dejará en el directorio DESTINATION_DIR todo el contenido listo para ser navegado.

  • El parámetro –image-snapshot, asegura la copia de las imágenes subidas

Configuraciones

Se pueden indicar otros parámetros para

  • -k <SKIN>: utilizar un skin en particular. El contenido respaldado apunta dicho skin en la wiki , por lo que requiere que esté en funcionamiento y sea accesible para que el skin sea visualizado correctamente.
    • Si no se especifica o bien si se indica el skin “offline”, se utiliza un skin básico disponible dentro del contenido respaldado.
  • –munge-title <ALGORITHM>: utilizar un algoritmo para transformar los nombres de páginas y archivos cuando contienen caracteres no soportados por el entorno desde el que se accederá al contenido.
    • md5: se transforman los nombres a partir de aplicarles MD5 (útil si existen caracteres UTF8)
    • windows: se quitan los caracteres no soportados en nombres de archivos en Windows ( /\*?”<>| )

Inconvenientes

No pude hacer que se exporte el thumbnail de cada imagen, que se visualizan en la página de la imagen.

En la versión 1.19 de MediaWiki me sucedieron 2 cosas:

En la primer ejecución, obtuve el error "Default users are not allowed to read, please specify (--group=sysop)". Pude solucionarlo agregando a la invocación

--group=user

Había realizado la exportación indicando el skin monobook, pero no se visualizaba correctamente y pude observar que se intentaban obtener los estilos desde "http://localhost/load.php?...". Pude solucionarlo estableciendo la url de la wiki en una variable de configuración de LocalSettings.php:

$wgServer = 'http://www.dominio-wiki.com';

y volviendo a exportar para que se apuntara correctamente al skin.

Agregar marcador con palabra clave en Firefox

Firefox permite crear marcadores donde cada uno tenga asociada una palabra clave, de manera que se pueda utilizar como una búsqueda rápida de contenido en el sitio vinculado. Para ello, al agregar o modificar un marcador debemos indicar:

  • Dirección: Una URL que contenga la cadena “%s” (sin las comillas) en el querystring, es decir, después del “?”
  • Palabra clave: Una palabra que se asocie al tipo de búsqueda y/o al sitio donde se realizará

Luego, al escribir en la barra de direcciones la palabra clave, seguida de un espacio y un valor, se invocará la dirección asociada a dicha palabra clave y se reemplazará la cadena %s por el valor previamente indicado.

 

Ejemplos:

Vamos a ver unos ejemplos con el sitio Bugzilla de Mozilla

  1. Si accedemos seguido a los bugs allí cargados por su identificador, podemos crear un marcador:

Al escribir en la barra de direcciones: “bug 314”, se accederá a la dirección “https://bugzilla.mozilla.org/show_bug.cgi?id=314&#8221;

  1. Si queremos buscar bugs a partir de ciertos términos podemos crear un marcador:

Al escribir en la barra de direcciones: “search blank name”, se accederá a la dirección “https://bugzilla.mozilla.org/buglist.cgi?quicksearch=blank%20name&#8221;

 

TIP: En todo lugar donde vean un input de texto que permita llevar a cabo una búsqueda, Firefox asiste en la creación del marcador si hacemos:

  1. Click derecho sobre el input de texto
  2. Elegir la opción “Agregar una palabra clave a esta búsqueda…”
  3. Completar la plabra clave del marcador (la Dirección la obtiene internamente Firefox)
  4. Guardar para confirmar

Acceder a página protegida con htaccess mediante Perl (LWP)

Ya vimos como acceder a una página que se encuentra protegida por htaccess desde un script PHP (con curl y con file_get_contents). Ahora vamos a hacer lo mismo con LWP en Perl. Las principales diferencias con los métodos vistos para PHP son que en este caso se debe indicar junto a las credenciales:

  • el dominio con el puerto
  • el “realm” (ámbito), que representa el valor del AuthName definido en el archivo htaccess.
    • Importante: Deben coincidir perfectamente

Entonces, el bloque de código modelo para implementar LWP es el siguiente:

 #!/usr/bin/perl
 use strict;
 use LWP;
 
 my $url = 'http://www.destino.com/secure/index.cgi';
 
 my $domain = 'www.destino.com';
 my $port = 80;
 my $username = 'ht_user';
 my $password = 'ht_pass';
 my $realm = 'Secured directory';
 
 my $ua = LWP::UserAgent->new();
 
 //Credenciales htaccess 
 $ua->credentials( "$domain:$port", $realm ,$username => $password);

 my $response = $ua->get($url);

 print "Content-type:text/html\n\n";
 my $data = $response->content;

En este ejemplo, obtendremos dentro la variable $data el contenido de la página index.cgi, para poder utilizarlo en el resto del script.

Se puede utilizar este medio para invocar otros scripts que devuelvan urls, json, etc. como si fuera un API a la aplicación.

 

Si desconocemos el “realm” podemos obtenerlo haciendo un get inicial de la url sin credenciales y leyendo el header WWW-Authenticate de la respuesta. El resultado para el ejemplo presentado devolvería:

Basic realm="Secured directory"