Linux

Command line tricks

SOME TIPS TO DO USEFUL TRICKS

These programs, scripts and commands have been tested on Ubuntu/Debian distributions of Linux. Feel free to contact me at fgonzalez[at]lpmd.cl

MANIPULATING TEXT FILES/DATA

MANIPULATING PHOTOS/VIDEOS/PDF

INTERNET

OPERATIVE SYSTEM

GNUPLOT


MANIPULATING TEXT FILES/DATA

July 28, 2021

FINDING FILES

  • To find a file by its name, from the current directory (.), we use
 find . -iname "archivo"
The option -iname ignores differences between lower and upper case.
  • We can find a file by its extension, for example, all .pdf files:
find . -iname "*.pdf"
  • We can look for files and words inside them. For example, to find all .cc files (C++ sources) in the folder Programs/, and show only those that contain the word cmath, we excecute
find Programs/ -iname "*.cc" -exec grep "cmath" {} +
  • Find only files (exclude folders) that were modified on December in the folder "~/examples"
find ~/examples/ -type f -exec ls -ltr {} + | grep "Dec"
  • We can use 'find' to check that each file of a certain directory is identical to another one, with the same name, in another directory:
find directory1/ -type f -exec diff -q  {} directory2/{}  \;
  • Exceptions (for example, do not consider .dat files):
find directory1/ -type f -not -name "*.dat" -exec diff -q  {} directory2/{}  \;
  • Find all files that have modified in the last 30 days:
find . -type f  -mtime -30d -exec ls -ltr {} +

When using -exec in find, the symbol {} represents the file that was found in the search.

  • You can find and compress (simultaneously) all the big (heavier) files using
find . -type f -and -not -name "*.gz" -size +200k -exec gzip -v -f  {} +
  • What have you been doing lately? Find files that are newer than 2 months and older than 1 month.
find . -type f -newermt "$(date -d '2 months ago' '+%Y-%m-%d')" ! -newermt "$(date -d '1 month ago' '+%Y-%m-%d')" -exec ls -ltr {} +

November 29, 2010

SEARCHING INSIDE FILES

To find words or a chain of characters inside a text file (like "words.txt"), we use the grep command. For example, to find all lines in the file that start with any uppercase, type

 grep '^[A-Z]' words.txt

If we are looking for any line that starts with uppercase o any digit, we can do it by

 grep '^[A-Z1-9]' words.txt

Looking for lines that end in lowercase:

 grep '[a-z]$' words.txt

Looking for a particular word, like "apple" in the file "words.txt":

 grep 'apple' words.txt

This will look for the sequence of characters "apple" contained inside any word in the text (results may include 'apple15', 'myappleFRUIT', 'this apple'). Conversly, if we want all the lines in which "apple" DOES NOT APPEAR, we use

 grep -v 'apple' words.txt

PD: I recommend adding the follwing line in your ".bashrc" (LINUX) / ".bash_profile" (MacOS X):

 alias grep='grep --color=auto'

This alias will turn on the colors on your command line when using grep.


MANIPULATING PHOTOS/VIDEOS/PDF

MANIPULATING PHOTOS/VIDEOS/PDF

December 12, 2021

TRIM/CROP IMAGES (ELIMINATE BORDERS)

We can trim the borders of an image that is surrounded by a monochromatic background (one color) and get just the figure at the center using the command convert (ImageMagick):

convert original.png -trim -geometry 500x final_noborders.png

The command -geometry 500x is optional, and it is used to control the width of the resulting image to 500 pixels (the height is scaled proportionally).

January 23, 2016

MERGE PICTURES IN A SINGLE IMAGE

Using the command convert:

convert image1.png image2.png image3.png image4.png image5.png  -append  final.png

In a more compact notation,

convert image{1..5}.png -append  final.png

If we want the pictures from left to right, we change -append by +append

convert image{1..5}.png +append  final.png

January 23, 2016

REDUCE THE FILE SIZE OF A PDF

If we want to save space in the hard drive, we can make a PDF lighter, looking exactly the same, but using less resolution. We can do it using the program Ghostscript (gs):

gs -sDEVICE=pdfwrite -g10000x14151 -dNOPAUSE -dBATCH -dPDFFitPage  -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE   -sOutputFile=reduced-pdf.pdf original-file.pdf

We can change the resolution by changing -g10000x14151 to different page geometries, or simply use -sPAPERSIZE=a4. If the pdf is made up by pictures only (see Merge/join many PDF files (or images) in a single PDF below), we can combine pdfimages (to extract the images) with convert (to reduce the size of the images), and then merge all together using pdftk and sam2p. It is basically a mix of what we show in the tricks below:

#!/bin/bash

# The PDF file is an argument of the program
for myPDF in "$1" #*.pdf
do
 folder=$(echo $myPDF|sed -e 's/.pdf//')
 mkdir -p "$folder"
 cd "$folder"
  cp ../"$myPDF" .
  pdfimages -j "$myPDF" myimages
  for i in myimages*ppm; do convert -geometry 800 "$i" "$i".jpg; done
  for f in myimages*.jpg;do sam2p -j:quiet "$f" PDF: "$f".pdf ; done
  rm "$myPDF" myimages*ppm myimages*jpg
  pdftk myimages*.pdf cat output newfile.pdf
  rm myimages*pdf

  pages_new=$(pdfinfo newfile.pdf | grep Pages|awk '{print $2}')
  pages_old=$(pdfinfo "../$myPDF" | grep Pages|awk '{print $2}')
  size_new=$(pdfinfo newfile.pdf | grep "File size"|awk '{print $3}')
  size_old=$(pdfinfo "../$myPDF" | grep "File size"|awk '{print $3}')
  if [ $pages_new == $pages_old ]; then
#   echo "They have" $pages_new "pages both"
   if [ $size_new -lt $size_old ]; then
    #echo "The new one is lighter:" $size_new "vs antiguos" $size_old
    echo "The new $myPDF is lighter."
    mv newfile.pdf "../$(echo $myPDF|sed -e 's/.pdf/_v2.pdf/')"
   else
    echo "The new $myPDF is heavier than before. Reducction did not work. Erasing new one..."
    rm newfile.pdf
   fi
  else
   echo "WARNING: the amount pages is not the same"
  fi
 cd ..
 rmdir "$folder"
done

March 21, 2022

CREATE A GIF FROM A VIDEO FILE

If we have a video and we want to create a gif animation, we can use the program mplayer to split the video in a series of images:

mkdir output
mplayer -ao null myvideo.mp4 -vo jpeg:outdir=output

o the program ffmpeg:

mkdir output
ffmpeg -i myvideo.mp4 output/'%03d.png'

o the command convert (ImageMagick):

mkdir output
convert myvideo.mp4 -transparent white output/frame-%03d.png

The format %03d specifies the fixed number of digits (characters) for the output file names (001.png, 002.png, ..., 500.png), where each image corresponds to a respective frame of the video. This will divide the video in a number of images in format jpeg or png, which will be stored in the directory output/. The option -transparent white removes the white color of the images and replaces it by a transparent background. Then, using the command convert, we can merge them in a single gif file:

convert output/* output.gif

If the gif animation moves too slow or the file is too heavy, we can simply eliminate certain intermediate frames. For example, if we have 500 frames in the files 001.png, 002.png, ..., 500.png, we can filter every 5 frames using

convert output/{001..500..5}.png output.gif

This will only use the frames 001.png, 006.png, 011.png, ..., and 496.png to create the gif file.

Sometimes it is possible to optimize the gif file (make it lighter) with the option -fuzz

convert output.gif -fuzz 75% -layers Optimize optimised.gif

The higher the value of fuzz, the smaller the space in the disk it uses.

30 de Octubre, 2015

SCALING IMAGES OR PHOTOS

Suppose we have a folder with photos in jpg format, taken with a digital camera. If the photos were taken at high resolution, they will be quite large, making them difficult to send by email or taking up too much hard drive space. To reduce all the photos in size with a single command, run this in the folder:

 mkdir new; ls -1 *.jpg | sed 's/.*/convert -geometry 1024x768 & new\/&/' | sh

This creates a folder named "new" inside the current folder, and places the scaled photos (resized to 1024x768, which is a common standard size) there, without being too large (~300Kb).

  • You can also add a prefix to the photo names by inserting it before the "&" symbol. For example, changing "&" to "s_&" will cause a source photo called photo.jpg to be scaled and saved in the "new" folder with the name "s_photo.jpg".
  • If you don’t want to create a new folder inside the photo folder, but prefer to leave the scaled photos in the same folder with a different name, run:
 ls -1 *.jpg | sed 's/.*/convert -geometry 1024x768 & .\/s_&/' | sh

This will create the new scaled photos with the "s_" prefix to distinguish them from the originals.

October 30, 2015

EXTRACTING IMAGES FROM A PDF

To extract all images from a PDF file in JPG format, you can use the program pdfimages:

pdfimages -j myfile.pdf myimages

If the -j option fails to convert the images to JPG format and leaves them in PPM format (which can happen), we can convert them using the program convert:

for i in *ppm; do convert -geometry 800 "$i" "$i".jpg; done

The -geometry 800 option scales the image to 800 pixels in WIDTH, adjusting the height to maintain the aspect ratio. You can also use

for i in *ppm; do convert -geometry x800 "$i" "$i".jpg; done

With -geometry x800, the image is scaled to 800 pixels in HEIGHT, adjusting the width to maintain the aspect ratio.

June 10, 2013

MERGING MULTIPLE PDFs (OR PHOTOS) INTO A SINGLE PDF

If you have many jpg files and want to create a single PDF document from them, here’s a way to do it. You need to have the programs sam2p and pdftk installed:

sudo apt-get install sam2p pdftk

Now, convert the jpg files into PDF files:

for f in *.jpg; do sam2p "$f" PDF: "$f".pdf; done

With the following command, we combine the newly created PDF files (*.pdf) into a single file called newfile.pdf:

pdftk *.pdf cat output newfile.pdf

However, a quicker way to concatenate PDFs is to use Ghostscript:

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=newfile.pdf *.pdf

All in one program

Based on these commands, I wrote a script that, when run inside a folder of photos, creates a PDF one directory above (where the folder is located):

#!/bin/bash

for i in */
do
 if [ -f "$i" ]; then cd "$i"; fi
 # Gathering PNG pics
 if [ "$(find . -maxdepth 1 -iname "*png" | wc -l)" -gt "0" ]; then
  echo -n "PNG format in "
  pwd
  for f in *.png; do sam2p -j:quiet "$f" PDF: "$f".pdf; done
  pdftk *.pdf cat output newfile.pdf
  rm *png.pdf
 # Gathering JPG pics
 elif [ "$(find . -maxdepth 1 -iname "*jpg" | wc -l)" -gt "0" ]; then
  echo -n "JPG format in "; pwd
  for f in *.jpg; do sam2p -j:quiet "$f" PDF: "$f".pdf; done
  pdftk *.pdf cat output newfile.pdf
  rm *jpg.pdf
 else
  echo -n "No jpg or png photos found in "; pwd
 fi

 new="../$(basename "$PWD").pdf"
 if [ -f newfile.pdf ]; then
  mv newfile.pdf "$new"
  echo "$(basename "$PWD").pdf created successfully."
 fi
 if [ -f "$i" ]; then cd ..; fi
done

November 29, 2010

MENCODER / FFMPEG: Manipulating videos

Primero, descarga el programa mencoder:

 sudo apt-get install mencoder

CONVERTIR FORMATO DE VIDEO

Para simplemente cambiar el formato de un video, por ejemplo, de ogv a avi, utiliza el comando

 mencoder pelicula.ogv -ovc copy -oac copy -o pelicula.avi

En este caso, el codec de video es simplemente copy, para que copie el video y el audio sin cambiar nada más que el formato. Para convertir de mp4 a MPEG, podemos utilizar

mencoder  planet-formation.mp4  -of mpeg -ovc lavc -lavcopts vcodec=mpeg1video  -oac copy -o pelicula.mpg

SUBTITULAR PELÍCULAS

En este caso, debes cambiar el codec de video por lavc y estar en posesión (descargar) los subtítulos en formato srt. Luego los pegas al video usando el comando

 mencoder pelicula.avi -sub subtitulos.srt -ovc lavc -oac copy -o pelicula-sub.avi

REDUCIR LA CALIDAD (AHORRAR MEMORIA)

Un comando asociado a mencoder es ffmpeg que funciona tanto en Linux como MacOS. Podemos reducir el tamaño de un video simplemente disminuyendo el bitrate:

ffmpeg -i input.mp4 -b 800k output.mp4

SLICE A VIDEO (Cut a video)

To extract a portion of a video, we can use the command

ffmpeg -ss 00:03:54 -I original-video.mp4   -c:v copy -t 00:01:12 -an  output-video.mp4

where 00:03:54 represents the instant where we want the new video to start at, and 00:01:12 (1 minute y 12 seconds) represents the duration of the video from the instant given by the start time.


INTERNET

July 28, 2021

rsync: Synchronize files between two computers

The rsync command works similarly to scp: the goal is to copy the files from the source computer to a destination (another computer or directory). But the advantage of rsync over scp is that it can copy only the new files or recently modified ones, such that one avoids copying entire folder every time. Thus, it is possible to keep two directories synchronized copying just what is strictly necessary.

Bring files to your computer

If you are logged in to a remote computer (host), like a computer cluster, and your username is myname, and you want to copy all directories named, say, Fe001, Fe002, Fe003, etc., you can do:

rsync -avuz  myname@host:Fe* .

If you type the same command immediately after, the files will not be copied again, because the program detects that the sources files are identical as the destination files. The program generates a list of files to copy that then copies. Here, we are using -a (file mode) -v (increased verbosity) -u (omit files that already exist in the destination and have a more recent time stamp than the source file) and -z (compress during transfer).

Generate the list of files to copy (debug)

Sometimes it is very useful to obtain the list of files that are going to be copied before actually transferring them, just to verify that those are actually the files we want to copy. Thus, we avoid replacing files by mistake. What we do, is simply omitting the destination:

rsync -avuz  myname@host:Fe*

This command looks almost identical to the one above, but we have removed the dot ( . ) that represent the current destination directory (the one from which we are typing the command). The program prints the list of files that would have been transferred if we had gave it the destination directory.

Copy only certain files from the source

rsync -avuz --include='*/' --include='*.dat' --exclude='*'  --prune-empty-dirs  myname@host:Fe* .

In this case, we are synchronizing the same directories as above, but we are copying only the files in them that end in .dat with the directories. For further informations about how to write patters of files, read the rsync manual.

Copy everything, EXCEPT...

rsync -avuz --exclude='XDATCAR'  --exclude='OUTCAR' --exclude='*.xml'  myname@host:Fe* .

In this example, we are copying all the directories with all their files, except those ones that are named "XDATCAR", "OUTCAR," and those whose name ends in ".xml". This is particularly useful for VASP users.

Copy only small files

rsync -avuz --max-size=200kb --prune-empty-dirs  myname@host:Fe* .

Here, we are copying all directories that start with Fe but only if they weigh less than 200 kilobytes.

You can find and compress (simultaneously) all the big (heavier) files before transferring them using

find . -type f -and -not -name "*.gz" -size +200k -exec gzip -v -f  {} +

Check out the find command.

Releasing space: remove files from the source after copying them

rsync -avuz --prune-empty-dirs --remove-source-files myname@host:Fe* .

This will copy all the files to the destination and delete them from the source, where they are being copied from. It will still leave empty folders behind in your source, which you can delete using

rmdir */*;   rmdir *

or

find . -type d -empty -delete

I recommend executing the same command but without the --remove-source-files option first, just to make sure that the files were copied correctly before eliminating them; but this is not necessary in theory because the command will only eliminate them if they were successfully copied.

More info about rsync: https://phoenixnap.com/kb/rsync-exclude-files-and-directories

29 de Noviembre, 2010

SCP: Copiar archivos de un computador a otro

Entre dos computadores (con linux) conectados a la misma red:

Supongamos que estás en tu casa, oficina o cualquier lugar en donde tengan internet, y todos están conectados al mismo router, switch, etc (están todos en la misma red local).

Si estas usando tu laptop, y quieres copiar un archivo al pc de escritorio, averigua el IP del PC de escritorio. Si este tiene linux, en la terminal de ese PC ejecutas

ifconfig

Si el computador está conectado por cable, el IP aparecerá en eth0. Si está conectado por WiFi, estará en wlan0. Será algo como 192.168.1.2. Si el archivo que quieres copiar se llama file.txt y está en tu laptop con linux, y quieres copiarlo a este PC de escritorio que tiene ese IP, ejecuta

 scp file.txt casa@192.168.1.2:

En este comando, el primer argumento de scp es el archivo de origen que se encuentra en tu laptop, y el segundo, el lugar de destino, donde casa es el nombre del usuario y 192.168.1.2 es el IP interno. Este número IP lo puedes conseguir dando ifconfig (saldrá en donde dice wlan0 si estás conectado por red inalámbrica, o en eth0 si estás conectado por red cableada).

Si estas usando tu laptop, y quieres copiar en este un archivo que está en el pc escritorio, digamos file2.txt, da el comando

 scp casa@192.168.2.5:/home/casa/file2.txt .

Esto copia el archivo file2.txt, que se encuentra en el directorio /home/casa/file2.txt del pc en el directorio del laptop desde el cual diste el comando (el punto "." significa "copiar aqui"). Puedes reemplazar el punto por cualquier otro directorio en el laptop que desees.

Si estás en el pc de escritorio y quieres copiar algo al laptop, la filosofía es la misma:

 scp file2.txt laptopUSR@192.168.1.5:

En este caso, el IP del laptop es distinto (y el usuario, en general, también) y puedes obtenerlo con ifconfig como antes. Este comando copia file2.txt desde el pc al home del usuario laptopUSR en el laptop. Puedes especificar el directorio de llegada en el caso de que no quieras copiarlo en el home:

 scp file2.txt laptopUSR@192.168.1.5:/home/laptopUSR/carpeta/subcarpeta/

Si estás en el pc de escritorio y quieres sacar algo del laptop, entonces digita

 scp laptopUSR@192.168.1.5:/home/laptopUSR/file.txt .

Dejar copiando con nohup (se puede cerrar sesión)

Si un archivo es muy grande o la conexión es muy lenta, la transferencia de archivos puede demorar mucho, a veces más del tiempo que tenemos disponible frente a la computadora. Para poder dejar scp ejecutándose en el background, y así poder cerrar la sesión, debemos dar el siguiente comando:

 nohup scp -r -p usr@192.168.1.5:Folder/subfolder/  .  > nohup.out  2>&1

En este caso, estamos trayendo la carpeta subfolder/ completa (con la opción -r, y conservando las fechas de creación con -p) desde el directorio /home/usr/Folder/ que está en el servidor de número IP 192.168.1.5, al directorio actual (desde donde estamos ejecutando el comando ( . )). Luego de esto, nos pedirá la clave para ingresar al servidor. Después de escribirla, dejamos el proceso suspendido en el background con CTRL+Z. Finalmente, dejamos el proceso ejecutándose en el background con el comando

Copiar multiples archivos con un patrón

Si en un servidor tenemos, por ejemplo, los archivos arch1.pdf, arch2.pdf, ..., arch55.pdf; pero sólo queremos copiar algunos de ellos, podemos hacerlo si ellos siguen un patrón. Por ejemplo, si sólo queremos los con número par, entre el arch12.pdf y arch40.pdf, lo podemos hacer de la siguiente manera:

 scp -r -p usr@192.168.1.5:Folder/arch\{12..40..2\}.pdf  .

29 de Noviembre, 2010

BAJAR VARIOS ARCHIVOS DE INTERNET SIMULTÁNEMENTE

Digamos que tienes muchos archivos de fotos con extensión ".jpeg" en la pagina 'http://zeth.ciencias.uchile.cl/~mipagina'. Puedes bajar todos los archivos de esa carpeta (mipagina) con

wget -e robots=off -r -l1 --no-parent -A.jpeg http://zeth.ciencias.uchile.cl/~mipagina

NO SIRVE bajarlos con

wget http://zeth.ciencias.uchile.cl/~mipagina/*.jpeg

ya que esto solo funciona para sitios ftp.

Obviamente puedes bajar otro tipo de archivos, cambiando "-A.jpeg" por "-A.pdf", "-A.gif" o lo que sea.

29 de Noviembre, 2010

CONVERTIR VIDEOS DE YOUTUBE EN MP3

¿Quieres bajar música de YouTube? Aqui está la solución. Baja el ffmpeg:

sudo apt-get install ffmpeg

Solo por si acaso, instala libavcodec-extra-53:

sudo apt-get install libavcodec-extra-53

Ahora anda a FireFox, y baja el Add-On llamado "Video DownloadHelper 4.7.3". Cuando lo instales, va a aparecer un símbolo (3 bolitas de colores) a la izquierda de la barra del explorador, que se comenzará a mover cuando te metas a una página aceptada por el programa (YouTube, Google Video, National Geographic, hay montones...). Cuando estes viendo el video que te interesa, simplemente das click en la flechita al lado del símbolo giratorio y lo descargas.

Ahora, con el video descargado en un directorio a tu elección, das el comando

ffmpeg -i mi_archivo_de_youtube.flv mi_cancion.mp3

El formato flv es el formato por defecto de los videos de YouTube. Ahora puedes bajar discos completos de YouTube :P

Este es un programa que convierte todos los flv de una carpeta en mp3:

#!/bin/bash
# conversor de archivos de youtube a mp3
for i in $(ls *.flv);
do
 orig=$i
 dest=$(echo $i | sed -e "s/.flv/.mp3/")
 ffmpeg -i $orig $dest
done

Lo guardan en un archivo que se llame flv-to-mp3.sh y lo ejecutan en la carpeta donde están sus archivos:

./flv-to-mp3.sh

Acuérdense de darle los permisos de ejecución antes de ejecutar (chmod 755 flv-to-mp3.sh).

29 de Noviembre, 2010

CONECTAR A INTERNET DESDE LA TERMINAL

Listar las redes:

 iwlist wlan0 scanning

Esto debería listar las redes disponibles. Elegir la red que corresponda (En mi scanning dice ESSID: "fisica"):

 iwconfig wlan0 essid fisica

Conectar:

 dhclient wlan0


SISTEMA OPERATIVO

29 de Noviembre, 2010

CONVERTIR ARCHIVOS .rpm Y .tar.gz A UN .deb

Esto es útil para los usuarios de Debian/Ubuntu, ya que los paquetes .deb, a diferencia de los otros comprimidos, se instalan sólo con doble click o dpkg -i paquete.deb sin necesidad de descomprimir.

Necesitarás alien, asi que instalalo con

 sudo apt-get install alien

El comando

 alien -d archivo.rpm

convierte el .rpm a .deb. Si deseas convertirlo e instalarlo con un solo comando, ejecuta

 alien -i archivo.rpm

Para convertir el .tar, ejecuta

tar xfz nombre-del-paquete.tar.gz
cd nombre-del-paquete
./configure
make
sudo checkinstall
 

29 de Noviembre, 2010

MONTAR PEN-DRIVES

 mount -t vfat /dev/sdb1/ /media/nombre_de_la_carpeta

29 de Noviembre, 2010

HACER DVD

Escribir imagen .iso de DVD:

 readom dev=/dev/cdrom f=imagen.iso

Quemar imagen .iso a DVD:

 growisofs -Z /dev/cdrom=imagen.iso

29 de Noviembre, 2010

CAMBIAR EL FONDO DE LA PANTALLA DE LOGIN EN UBUNTU 10.04

Como se habrán usado los usuarios de Ubuntu 10.04, la pantalla de inicio (donde uno elije el usuario y da la contraseña) es, en principio, inmutable. Pero hay buenas noticias: el fondo se puede cambiar. El comando que hace la gracia es

 gksu -u gdm dbus-launch gnome-appearance-properties

que abre la misma pantalla de opciones que aparece cuando queremos cambiar el fondo de escritorio, sólo que esta vez se lo estaremos haciendo al fondo de la pantalla de bienvenida.