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: Working with Videos

First, install the mencoder tool with the following command:

 sudo apt-get install mencoder

CONVERT VIDEO FORMAT

To simply change a video’s format—for example, from `.ogv` to `.avi`—use:

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

This copies the video and audio without re-encoding, only changing the container format.

To convert a `.mp4` file to MPEG format, use:

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

ADD SUBTITLES TO A VIDEO

To add subtitles (in `.srt` format), you need to re-encode the video with the `lavc` codec. Use:

 mencoder movie.avi -sub subtitles.srt -ovc lavc -oac copy -o movie-sub.avi

This embeds the subtitles into the video stream while keeping the original audio.

REDUCE VIDEO QUALITY (SAVE SPACE)

To reduce the file size of a video by lowering the bitrate, use ffmpeg (available on both Linux and macOS):

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

This is useful for saving disk space or uploading smaller files.

TRIM A VIDEO (Extract a Portion)

To extract a specific segment from a video, use:

 ffmpeg -ss 00:03:54 -i original-video.mp4 -c:v copy -t 00:01:12 -an output-video.mp4
  • `-ss 00:03:54`: start time of the clip (HH:MM:SS)
  • `-t 00:01:12`: duration of the clip
  • `-an`: disables audio (remove this if you want to keep the audio)


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: Copy files from one computer to another

Between two computers (with Linux) connected to the same network:

Suppose you're at home, at the office, or anywhere with internet, and all your devices are connected to the same router or switch (i.e., they're on the same local network).

  • If you're using your laptop and want to copy a file to your desktop PC, you first need to find out the IP address of the desktop. If it runs Linux, open a terminal on that computer and run:
ifconfig
  • If the PC is connected by cable, the IP will appear under eth0. If it's on WiFi, it'll be under wlan0. It'll look like 192.168.1.2.
  • If you have a file called file.txt on your laptop and want to copy it to your desktop PC, run:
scp file.txt home@192.168.1.2:
  • Here, file.txt is the file on your laptop. home is the username on the desktop PC, and 192.168.1.2 is the IP you got from ifconfig.
  • If instead you want to copy a file from the desktop PC to your laptop, say the file file2.txt, you can run:
scp home@192.168.2.5:/home/home/file2.txt .
  • This command copies the file from the desktop to your laptop's current directory (the dot ``"."`` means "here").
  • If you're on the desktop and want to copy something to the laptop, use the same approach. For example:
scp file2.txt laptopUSR@192.168.1.5:
  • Here, laptopUSR is the username on the laptop and 192.168.1.5 its IP, which you can get with ifconfig. The file will go to the home directory by default.
  • To specify a different target folder, use:
scp file2.txt laptopUSR@192.168.1.5:/home/laptopUSR/folder/subfolder/
  • If you're on the desktop and want to copy something from the laptop, run:
scp laptopUSR@192.168.1.5:/home/laptopUSR/file.txt .

Leave copy running with nohup (to log out without stopping the transfer):

  • If you're copying a large file or folder and it will take a long time, you can use nohup so the process continues even if you log out:
nohup scp -r -p usr@192.168.1.5:Folder/subfolder/ . > nohup.out 2>&1
  • In this command:
    • -r copies the folder recursively.
    • -p preserves original timestamps.
    • usr is the remote user's name.
    • The file will be copied to the current directory (``"."``).
    • Output is saved to nohup.out.
  • After entering your password, you can suspend the process with **CTRL+Z** and then resume it in the background with:

Copy multiple files with a pattern:

  • If you want to copy only some files matching a pattern (e.g., the files arch12.pdf, arch14.pdf, ..., arch40.pdf), you can use:
scp -r -p usr@192.168.1.5:Folder/arch\{12..40..2\}.pdf .
  • This copies all files with even numbers between 12 and 40 from the server to the current directory.

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.