Tag Archives: bash

Debian squeeze en Samsung N210

La semana pasada me compré una netbook Samsung N210 con la cual estoy muy contento. Le instalé Debian squeeze (testing) y logré configurarle todas las teclas especiales, incluyendo las usadas para regular el brillo de la pantalla. Me basé en varias guías como esta y esta otra, aunque no las seguí exactamente y es por eso el motivo del post.

Antes de comenzar la guía (y suponiendo que como yo, estás leyendo esto antes de comprar la máquina) te cuento mi experiencia con este aparatito. Algo que me hacía dudar en comprarme o no una netbook era el teclado que traían: demasiado chicos o sin espacio entre teclas. La N210 tiene casi la misma distancia entre la A y la Ñ que los teclados de escritorio y además tiene las teclas separadas como para que los dedos reconozcan mejor dónde están ubicados. Lo encuentro bastante cómodo y agradable de usar y salvo por un par de teclas que complican un poco (la < se encuentra sobre la derecha y el shift derecho es chico) me siento a gusto con él. Por otro lado la batería dura aprox. 7 hs (con el brillo casi a tope) contra las 11 que declara Samsung. Dudo que llegue a eso incluso desconectando la wifi, bluetooth y poniendo el brillo al mínimo, pero aun así destaca su autonomía. Otra característica que me gusta es que es silenciosa y calienta muy poco.

Una última cosa antes de comenzar: El microprocesador Atom N450 tiene tecnología Hyperthreading que paraleliza el procesador físico en dos procesadores virtuales. Es por eso que la salida de/proc/cpuinfomuestra dos cpus.

Ahora sí, vamos a la guía.


Read more »

Tags: , ,

GNU gettext con php5

gnu-head-sm

GNU gettext es la biblioteca GNU de internacionalización (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.

wikipedia

La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el software para una región específica mediante la adición de componentes específicos de un locale y la traducción de los textos, por lo que también se le puede denominar regionalización.

Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization como “i18n”. Ello se debe a que entre la primera i y la última n de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia “L10n”.

gettext en PHP

Existen dos formas de usar gettext en PHP: mediante la extensión gettext nativa de PHP o utilizando la librería PHP-gettext, escrita en PHP, que no necesita ninguna extensión.

La forma de usar gettext es

1
2
3
4
# @file: index.php
<?php
print _("hello world");
?>

La función_(), alias degettext(), devolverá la cadena “hello world” en el lenguaje correspondiente, de acuerdo al locale que hayamos seleccionado.

Si ejecutamos el script obtendremos “hello world” como salida, puesto que no hemos indicado ningún locale, ni creado ningún catálogo de traducción. Necesitamos crear el archivocomments.pocon la traducción de la cadena “hello world”. Esto puede hacerse mediante el comandoxgettext, o mediante un editor gráfico como poEdit.

apt-get install poedit

Creación del catálogo con poEdit

Ante todo debemos saber que la estructura de directorios para guardar los distintos catálogos tiene forma determinada. Por cada traducción se utiliza un directorio. Este generalmente se nombra usando dos letras minúsculas para el idioma, un guión bajo y dos mayúsculas para el país (es_AR, para español de Argentina). Dentro de este directorio debe existir otro con el nombre LC_MESSAGES, el cual será finalmente el directorio que contendrá el catálogo.

La estructura de nuestro ejemplo será

.
|-- locale
|   `-- es_AR
|       `-- LC_MESSAGES
|           |-- messages.mo
|           `-- messages.po
`-- index.php

El archivomessages.moes la versión compilada demessages.poy el que usará PHP para obtener la traducción.

Iniciemos poEdit. La primera vez nos preguntará por nuestro nombre y correo electrónico. Estos datos servirán para saber quién fue el último traductor que modificó el catálogo. Una vez en la ventana principal vamos a File -> New catalog. Seleccionamos el idioma (Español en este caso), el país y el código de caracteres tanto para el catálogo como para la fuente de datos desde la que obtendremos el listado de cadenas que requieren traducción. En la solapa Paths debemos colocar en ‘Base path’ la ruta completa al directorio base de archivos php (conteniendo las cadenas mencionadas anteriormente) y, debajo, en el cuadro ‘Paths’ agregar una entrada con ‘.’ indicando que se debe utilizar el directorio ingresado anteriormente. Al hacer click en OK aparecerá un cuadro de diálogo para guardar el nuevo catálogo. Navegamos hasta el directorio LC_MESSAGES y guardamos el archivo como messages.po. poEdit escaneará el directorio ingresado en Paths y extraerá todos las cadenas gettext. Ahora queda simplemente realizar la traducción y guardar el archivo. Al guardarlo, poEdit lo compilará y generará el .mo que finalmente usará PHP.

Ahora, modificaremos index.php para setear el locale

1
2
3
4
5
6
7
8
9
10
11
12
13
# @file: index.php
<?php
$language = 'es_AR.UTF-8';
putenv("LANG=$language");
setlocale(LC_ALL, "");

$domain = "messages";
bindtextdomain($domain, "./locale");
bind_textdomain_codeset($domain, 'UTF-8');
textdomain($domain);

print _("hello world");
?>

Aun nos queda un paso y es comprobar que tengamos dicho locale habilitado en nuestro sistema. Esto lo hacemos mirando la salida de

locale -a

Si no tenemos habilitado el charset es_AR.UTF8, ejecutamos

locale-gen es_AR.UTF-8

En este punto la salida del script debería ser la traducción que hicimos al español.

Tip

Para casos en que la cadena a traducir contenga variables, podemos utilizar esta función:

1
2
3
4
5
6
7
8
9
10
function __($string)
{
    $arg = array();
    for($i = 1 ; $i < func_num_args(); $i++)
        $arg[] = func_get_arg($i);
    return vsprintf(gettext($string), $arg);
}

$total = 400;
print __("results %d - %d of about %d", 1, 20, $total);

La traducción podría quedar

resultados %d - %d de aproximadamente %d

Tags: , , ,

Crear un parche

Suponiendo el archivo

xleo@okkoto:/tmp$ cat file1
uno
2
tres
cuatro
seis

y su modificación

xleo@okkoto:/tmp$ cat file2
uno
dos
tres
cuatro
cinco
seis

creamos el archivo conteniendo las diferencias

xleo@okkoto:/tmp$ diff -u file1 file2 > file.patch

y finalmente aplicamos el parche

xleo@okkoto:/tmp$ patch < file.patch
patching file file1

Tags:

Generar rango numérico en Bash

Usando seq

Syntax:

seq LAST
seq FIRST LAST
seq FIRST INCREMENT LAST

Code:

$ seq 5 10
$ seq 0 2 10
$ seq 5 -1 1

Script:

#!/bin/bash
for i in `seq 5`
do
   echo "Welcome $i times"
done

Usando for

#!/bin/bash
for ((a=1; a<=5; a++))
do
   echo "Welcome $i times"
done

Tags:

Renombrar recursivamente archivos y directorios

El siguiente script de bash renombra archivos y directorios convirtiendo sus nombres a minúsculas, reemplazando espacios, acentos, eñes y eliminando paréntesis.

Por defecto renombra únicamente aquellos archivos y directorios ubicados en el directorio pasado como parámetro. Es posible usar la opción-r|--recursivepara que trabaje recursivamente en todos los directorios hijos:

./rename.sh -r dir

Usando la opción-v|--verbosees posible ver en pantalla el listado de archivos modificados

./rename.sh -v -r dir

La opción-t|--testmuestra un listado de cambios a realizar sin realizar ninguno

./rename.sh -t -r dir

Ejemplo

xleo@calcifer:/tmp/music$ rename -t -r .
/tmp/music/Jaime Roos/1998 - Concierto Aniversario
./17 - Amándote.mp3 ./17_-_amandote.mp3
./02 - Victoria Abaracón.mp3 ./02_-_victoria_abaracon.mp3
./12 - Nadie Me Dijo Nada.mp3 ./12_-_nadie_me_dijo_nada.mp3
./16 - Durazno Y Convención.mp3 ./16_-_durazno_y_convencion.mp3
./01 - Si Me Voy Antes Que Vos-1.mp3 ./01_-_si_me_voy_antes_que_vos-1.mp3
./03 - El Hombre De La Calle.mp3 ./03_-_el_hombre_de_la_calle.mp3
./05 - Las Luces Del Estadio.mp3 ./05_-_las_luces_del_estadio.mp3
./07 - Piropo.mp3 ./07_-_piropo.mp3
./10 - Esta Noche.mp3 ./10_-_esta_noche.mp3
./06 - Se Va La Murga.mp3 ./06_-_se_va_la_murga.mp3
./08 - Los Futuros Murguistas.mp3 ./08_-_los_futuros_murguistas.mp3
./15 - Tal Vez Cheché.mp3 ./15_-_tal_vez_cheche.mp3
./13 - Bienvenido.mp3 ./13_-_bienvenido.mp3
./1998 - Concierto Aniversario.m3u ./1998_-_concierto_aniversario.m3u
./09 - Los Olímpicos.mp3 ./09_-_los_olimpicos.mp3
./11 - Cometa De La Farola.mp3 ./11_-_cometa_de_la_farola.mp3
./04 - Cuando Juega Uruguay.mp3 ./04_-_cuando_juega_uruguay.mp3
./14 - El Tambor.mp3 ./14_-_el_tambor.mp3
/tmp/music/Jaime Roos
./1998 - Concierto Aniversario ./1998_-_concierto_aniversario
/tmp/music
./Jaime Roos ./jaime_roos

rename.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
#
# @autor   Leonardo Vidarte
# @version $Id rename.sh 5 2008-06-05 15:44:45Z xleo $
#


# ********
# INIT SET
# ********
verbose=0
recursive=0
MOVE=/bin/mv
ECHO=


# ****
# HELP
# ****
help () {
cat << END
Usage : rename [-t] [-v] [-r] directory

Options:
  -v, --verbose    verbose move
  -r, --recursive  recursive rename
  -t, --test       don't move, only show change list. Implies -v.
  -?, --help       show this help

END

}


# ***************
# RENAME FUNCTION
# ***************
rename () {
   
    find -maxdepth 1 | \
    awk '{out=tolower($0); \
    gsub(" ?\& ?","_y_",out); \
    gsub("\(|\)","-",out); \
    gsub("[\340-\345]","a",out); \
    gsub("\347","c",out); \
    gsub("[\350-\353]","e",out); \
    gsub("[\354-\357]","i",out); \
    gsub("\361","n",out); \
    gsub("[\362-\366]","o",out); \
    gsub("[\371-\374]","u",out); \
    gsub("[^0-9a-z\./_-]","_",out); \
    if ($0!=out) {print "\""$0"\" "out;}}'
| \
    xargs -r -n 2 $ECHO $MOVE

}


# *************
# MAIN FUNCTION
# *************
main () {


    # ----------------
    # Recursive rename
    # ----------------
    if [ $recursive -eq 1 ]; then

        for dir in "$1"/*
        do
            if [ -d "$dir" ]; then
                cd "$dir" && search "$dir"
            fi
        done

    fi


    # ----------------------------
    # Rename files and directories
    # ----------------------------
    if [ $verbose -eq 1 ]; then
        echo "$1"
    fi

    cd "$1" && rename


}


# ***************************
# SHOW HELP WITHOUT ARGUMENTS
# ***************************
if [ $# -eq 0 ]; then
   help
   exit 1
fi


# *********
# SHOW HELP
# *********
if [[ "$1" =~ '(-h|--help)' ]]; then
   help
   exit 0
fi


# ***************
# CHECK ARGUMENTS
# ***************
while [ $# -gt 1 ]; do

    case "$1" in

        -v|--verbose)
            verbose=1
            MOVE="$MOVE --verbose"
        ;;    
        -r|--recursive)
            recursive=1
        ;;
        -t|--test)
            verbose=1
            MOVE=
            ECHO=/bin/echo
        ;;    
        *)
            echo invalid argument $1
            help
            exit 2
        ;;

    esac

    shift

done


# ****************************************
# CHECK DIRECTORY AND INVOKE MAIN FUNCTION
# ****************************************
if [ "$1" == '.' -o "$1" == '*' ]; then
    dir=$PWD
else
    dir=$1
fi

if [ -d "$dir" ]; then
    cd "$dir"
    dir=$PWD
    cd - 1> /dev/null
    main "$dir"
    exit 0
else
    echo rename: directory not found
    exit 3
fi

Otro ejemplo

Salida de./rename -r -v /shared/music > result.txt

Tags: , , ,

Bash Regular Expressions

When working with regular expressions in a shell script the norm is to use grep or sed or some other external command/program. Since version 3 of bash (released in 2004) there is another option: bash’s built-in regular expression comparison operator “=~”.

Bash’s regular expression comparison operator takes a string on the left and an extended regular expression on the right. It returns 0 (success) if the regular expression matches the string, otherwise it returns 1 (failure).

In addition to doing simple matching, bash regular expressions support sub-patterns surrounded by parenthesis for capturing parts of the match. The matches are assigned to an array variable BASH_REMATCH. The entire match is assigned to BASH_REMATCH[0], the first sub-pattern is assigned to BASH_REMATCH[1], etc..

The following example script takes a regular expression as its first argument and one or more strings to match against. It then cycles through the strings and outputs the results of the match process:

#!/bin.bash

if [[ $# -lt 2 ]]; then
    echo "Usage: $0 PATTERN STRINGS..."
    exit 1
fi
regex=$1
shift
echo "regex: $regex"
echo

while [[ $1 ]]
do
    if [[ $1 =~ $regex ]]; then
        echo "$1 matches"
        i=1
        n=${#BASH_REMATCH[*]}
        while [[ $i -lt $n ]]
        do
            echo "  capture[$i]: ${BASH_REMATCH[$i]}"
            let i++
        done
    else
        echo "$1 does not match"
    fi
    shift
done

Assuming the script is saved in “bashre.sh”, the following sample shows its output:

# sh bashre.sh 'aa(b{2,3}[xyz])cc' aabbxcc aabbcc
regex: aa(b{2,3}[xyz])cc

aabbxcc matches
  capture[1]: bbx
aabbcc does not match

Tags: , ,

Consultas XPath desde la línea de comandos

Existe una aplicación llamada

xmlstarlet

que permite hacer consultas XPath a archivos XML.

Supongamos el siguiente archivo XML, al cual llamaremos libro.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<xml version="1.0" encoding="UTF-8">

<libro>

<titulo>Patas arriba<titulo>
<autor>Eduardo Galeano</autor>

<capitulo num="1" titulo="La escuela del mundo al revés">
    <seccion num="1" titulo="Educando con el ejemplo">
        <parrafo destacado="si">La escuela del mundo al revés es la más democrática de las instituciones educativas.</parrafo>

        <parrafo>El mundo al revés premia al revés.</parrafo>
    </seccion>

    <seccion num="2" titulo="Los alumnos">
        <parrafo destacado="si">Día tras día, se niega a los niños el derecho de ser niños.</parrafo>
      <parrafo>En el océano del desamparo, se alzan las islas del privilegio.</parrafo>
    </seccion>
</capitulo>

<capitulo num="2" titulo="Cátedras del miedo">
    <seccion num="1" titulo="La enseñanza del miedo">
        <parrafo destacado="si">En un mundo que prefiere la seguridad a la justicia, hay cada vez más gente que aplaude el sacrificio de la justicia en los altares de la seguridad.</parrafo>
        <parrafo>A mediados de 1982, ocurrió en Río de Janeiro un hecho de rutina: la policía mató a un sospechoso de hurto.</parrafo>
    </seccion>

    <seccion num="2" titulo="La industria del miedo">
        <parrafo destacado="si">El miedo es la materia prima de las prósperas industrias de la seguridad privada y del control social.</parrafo>
        <parrafo>"Nuestra mejor publicidad son los noticieros de la televisión", dice, y bien sabe lo que dice, uno de los especialistas en la venta de seguridad.</parrafo>
    </seccion>

</capitulo>

</libro>

Consultas

Obtener el título del libro:

xmlstarlet select -t -v //titulo libro.xml

Obtener el capítulo 1:

xmlstarlet select -t -v "//capitulo[@num='1']" libro.xml

Obtener el capítulo 2:

xmlstarlet select -t -v "//capitulo[2]" libro.xml

Obtener el capítulo 2 usando last():

xmlstarlet select -t -v "//capitulo[last()]" libro.xml

Obtener la sección 1 del capítulo 2:

xmlstarlet select -t -v "/libro/capitulo[@num='2']/seccion[@num='1']" libro.xml

Obtener los párrafos que contienen algún atributo:

xmlstarlet select -t -c '//parrafo[@*]' libro.xml

Obtener los párrafos no destacados del capítulo 1:

xmlstarlet select -t -c "/libro/capitulo[@num='1']//parrafo[not(@destacado)]" libro.xml

Parámetros

Syntax for templates: -t|--template <options>
where <options>
  -c or --copy-of <xpath>         - print copy of XPATH expression
  -v or --value-of <xpath>        - print value of XPATH expression
  -o or --output <string>          - output string literal
  -n or --nl               - print new line
  -f or --inp-name         - print input file name (or URL)
  -m or --match <xpath>           - match XPATH expression
  -i or --if <test-xpath>              - check condition <xsl:if test="test-xpath">
  -e or --elem <name>            - print out element <xsl:element name="name">
  -a or --attr <name>            - add attribute <xsl:attribute name="name">
  -b or --break            - break nesting</xsl:attribute></name></xsl:element></name></xsl:if></test-xpath></xpath></string></xpath></xpath></options></options>

Sitio oficial: XMLStarlet Command Line XML Toolkit

Tags: , ,

Bash Shell Shortcuts

Este post podría llamarse: “Sin razones para sacar la mano derecha de la línea media del teclado” :P

Una aclaración que vale hacer al respecto de esta lista es que el tratamiento de “palabras” es, a menos que se indique lo contrario, lexicográfico.

Crtl

Ctrl + a – Salta al comienzo de la línea
Ctrl + b – Mueve el cursor un caracter atrás
Ctrl + c – Termina el comando/programa
Ctrl + d – Borra el caracter bajo el cursor
Ctrl + e – Salta al final de la línea
Ctrl + f – Mueve el cursor un caracter adelante
Ctrl + h – Borra un caracter hacia atrás (símil Backspace)
Ctrl + k – Corta desde el cursor hasta el final de la línea
Ctrl + l – Borra la terminal
Ctrl + r – Búsqueda hacia atrás en la historia de comandos
Ctrl + t – Intercambia de posición las dos ultimas palabras de la línea
Ctrl + u – Corta desde el comienzo de la línea hasta la posición del cursor
Ctrl + w – Borra hacia atrás el token completo (no lexicográfico) (ver

Alt+Backspace

)
Ctrl x Ctrl e – Invoca a $EDITOR
Ctrl + xx – Mueve el cursor entre las dos ultimas posiciones en que se encontró
Ctrl + x @ – Muestra los nombres de host que pueden ser resueltos (/etc/hosts)
Ctrl + y – Pega (yank) lo cortado previamente con

Ctrl+k

o

Ctrl+u

Ctrl + z – Suspende/Detiene el comando

Alt

Alt + < – Trae la primera línea en la historia
Alt + > – Trae la última línea en la historia
Alt + ? – Muestra la lista de nombres que coinciden con lo escrito
Alt + * – Inserta como argumentos todos los nombres que coinciden con lo escrito
Alt + b – Mueve el cursor una palabra atrás
Alt + c – Capitaliza la palabra desde el cursor al final de la misma
Alt + d – Borra la palabra bajo el cursor
Alt + f – Mueve el cursor una palabra adelante
Alt + l – Convierte en minúsculas, desde el cursor al final de la palabra
Alt + n – Trae la línea siguiente en la historia (como flecha abajo)
Alt + p – Trae la línea anterior en la historia (como flecha arriba)
Alt + r – Deshace todos los cambios hechos a la línea
Alt + t – Intercambia de posición dos palabras adyacentes
Alt + u – Convierte en mayúsculas, desde el cursor al final de la palabra
Alt + Backspace – Borra hacia atrás la palabra (ver

Crtl+w

)


Read more »

Tags:

Liberado un curso de The Gimp

Vía Menéame >

José Sanchez, de la Universidad de Málaga, nos ofrece un curso del programa de retoque fotográfico por excelencia para Gnu/Linux. El curso se puede descargar en formato imprimible (pdf) y en version comprimida con las fuentes en ODT para modificarlo, siempre de acuerdo a su licencia cc: Reconocimiento-NoComercial-CompartirIgual.

Desde bash

for i in `seq 1 9` ; \
do wget http://sanchezrodri.googlepages.com/ManualGIMP_Cap$i.pdf; \
done

Tags: , ,

Caracteres de salto de línea

Mix entre un artículo de Xavier Noria sobre el famoso\ny datos de Wikipedia.

¿Qué es \n?

Por razones históricas no existe un único código para representar inequívocamente una nueva línea. El código ASCII 10 (0×0A) se conoce técnicamente como “new line”, pero la actual representación de newlines depende del sistema operativo o de la aplicación corriendo sobre éste.

Los códigos usados para representar newlines en sistemas basados en ASCII son:

  • LF: Line Feed,"\cJ", Unicode000A, ASCII0x0A,012,10.
  • CR: Carriage Return,"\cM", Unicode000D, ASCII0x0D,015,13.
  • CRLF: Ambos códigos juntos y en este orden.

Entonces, tenemos que existen tres tipos distintos de newlines, dependiendo del SO que se trate:

  • LF: Unix y sistemas tipo Unix como Linux, Mac OS X, AIX, Xenix, BeOS, Amiga, RISC OS y otros.
  • CR: Familia Apple II y Mac OS hasta la versión 9.
  • CRLF: Microsoft Windows, WinCE, DOS, OS/2, CP/M, MP/M, y otros.

Si abrimos un editor de texto, en tres computadoras distintas corriendo un SO de cada una de estas tres familias, y escribimos “x + Return + y"en cada una y guardamos el archivo, el resultado en disco es distinto. De acuerdo con la nomenclatura explicada arriba, veríamos estos bytes:

  • Ubuntu GNU/Linux:120.10.121
  • Mac OS 9:120.13.121
  • Windows NT:120.13.10.121


Read more »

Tags: ,