Solve real-world shell scripting problems with over 110 simple but incredibly effective recipes
Sarath Lakshman
Lectura muy recomendada, sobre las cosas que podemos hacer con bash. Pongo unos ejemplos que he destacado:
Modificar la extensión de los archivos de JPG a jpg
rename *.JPG *.jpg
Moficar según una expresión regular
</pre> <pre>rename 's/ /_/g' *</pre> <pre>
Buscar resultados en un diccionario
</pre> <pre>#!/bin/bash #Filename: aspellcheck.sh word=$1 output=`echo \"$word\" | aspell list` if [ -z $output ]; then echo $word is a dictionary word; else echo $word is not a dictionary word; fi</pre> <pre>
Presentar la frecuencia de las palabras de un archivo
</pre> <pre>#!/bin/bash #Name: word_freq.sh #Description: Find out frequency of words in a file if [ $# -ne 1 ]; then echo "Usage: $0 filename"; exit -1 fi filename=$1 egrep -o "\b[[:alpha:]]+\b" $filename | \ awk '{ count[$0]++ } END{ printf("%-14s%s\n","Word","Count") ; for(ind in count) { printf("%-14s%d\n",ind,count[ind]); } }'</pre> <pre>
Matched string notation (&)
In sed we can use & as the matched string for the substitution pattern such that we can use the matched string in replacement string. For example:
</pre> <pre>$ echo this is an example | sed 's/\w\+/[&]/g'</pre> <pre>
[this] [is] [an] [example] Here the regex \w\+ matches every word. Then we replace it with [&]. & corresponds to the word that is matched.
Substring match notation (\1)
& is a string which corresponds to match string for the given pattern. But we can also match the substrings of the given pattern. Let’s see how to do it.
</pre> <pre>$ echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'</pre> <pre>
this is 7 in a number It replaces digit 7 with 7. The substring matched is 7. \(pattern\)is used to match the substring. The pattern is enclosed in () and is escaped with slashes. For the first substring match, the corresponding notation is \1, for the second it is \2, and so on. Go through the following example with multiple matches: $ echo seven EIGHT | sed ‘s/\([a-z]\+\) \([A-Z]\+\)/\2 \1/’ EIGHT seven ([a-z]\+\) matches the first word and \([A-Z]\+\)matches the second word. \1 and \2 are used for referencing them. This type of referencing is called back referencing. In the replacement part, their order is changed as \2 \1 and hence it appears in reverse order.
Awk avanzado
</pre> <pre>$ seq 5 | awk 'BEGIN{ sum=0; print "Summation:" } { print $1"+"; sum+=$1 } END { print "=="; print sum }'</pre> <pre>
Passing a variable value from outside to awk By using the -v argument, we can pass external values (other than from stdin) to awk as follows:
</pre> <pre>$ VAR=10000 $ echo | awk -v VARIABLE=$VAR'{ print VARIABLE }'</pre> <pre>
1 There is a flexible alternate method to pass many variable values from outside awk. For example:
</pre> <pre>$ var1="Variable1" ; var2="Variable2" $ echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2</pre> <pre>
Variable1 Variable2 When input is given through a file rather than standard input, use:
</pre> <pre>$ awk '{ print v1,v2 }' v1=$var1 v2=$var2 filename</pre> <pre>
In the above method, variables are specified as key-value pairs separated by space (v1=$var1 v2=$var2) as command arguments to awk soon after the BEGIN, { } and END blocks.
Compressing or decompressing JavaScript
</pre> <pre>$ catsample.js | tr -d '\n\t' | \ tr -s ' ' \ | sed 's:/\*.*\*/::g' \ | sed 's/ \?\([{}();,:]\) \?/\1/g'</pre> <pre>
The output is as follows:
functionsign_out(){$("#loading").show();$.get("log_ in",{logout:"True"},function(){window.location="";});}
Let’s write a decompression script for making obfuscated code readable as follows:
$ cat obfuscated.txt | sed 's/;/;\n/g; s/{/{\n\n/g; s/}/\n\n}/g'
Acceder a gmail desde linea de comandos
</pre> <pre>#!/bin/bash Filename: fetch_gmail.sh #Description: Fetch gmail tool username="PUT_USERNAME_HERE" password="PUT_PASSWORD_HERE" SHOW_COUNT=5 # No of recent unread mails to be shown echo curl -u $username:$password --silent "https://mail.google.com/mail/ feed/atom" | \ tr -d '\n' | sed 's::\n:g' |\ sed 's/.*\(.*\)<\/title.*\([^<]*\)<\/ name> \([^<]*\).*/Author: \2 [\3] \nSubject: \1\n/' | \ head -n $(( $SHOW_COUNT * 3 ))</pre> <pre>
Bajar todas las imágenes de una pagina web
</pre> <pre>#!/bin/bash #Description: Images downloader #Filename: img_downloader.sh if [ $# -ne 3 ]; then echo "Usage: $0 URL -d DIRECTORY" exit -1 fi for i in {1..4} do case $1 in -d) shift; directory=$1; shift ;; *) url=${url:-$1}; shift;; esac done mkdir -p $directory; baseurl=$(echo $url | egrep -o "https?://[a-z.]+") curl –s $url | egrep -o "<img src="[^" alt="" />]*>" | sed 's/<img src="\&quot;\([^&quot;]*\).*/\1/g'" alt="" /> /tmp/$$.list sed -i "s|^/|$baseurl/|" /tmp/$$.list cd $directory; while read filename; do curl –s -O "$filename" --silent done < /tmp/$$.list</pre> <pre>
Twiter desde consola
</pre> <pre>#!/bin/bash #Filename: tweets.sh #Description: Basic twitter client USERNAME="PUT_USERNAME_HERE" PASSWORD="PUT_PASSWORD_HERE" COUNT="PUT_NO_OF_TWEETS" if [[ "$1" != "read" ]] && [[ "$1" != "tweet" ]]; then echo -e "Usage: $0 send status_message\n OR\n exit -1; fi if [[ "$1" = "read" ]]; then curl --silent -u $USERNAME:$PASSWORD friends_timeline.rss | \ grep title | \ tail -n +2 | \ head -n $COUNT | \ sed 's:.*\([^<]*\).*:\n\1:' $0 read\n" http://twitter.com/statuses/ elif [[ "$1" = "tweet" ]]; then status=$( echo $@ | tr -d '"' | sed 's/.*tweet //') curl --silent -u $USERNAME:$PASSWORD -d status="$status" http:// twitter.com/statuses/update.xml > /dev/null echo 'Tweeted :)' fi</pre> <pre>
define: de google desde consola
</pre> <pre>#!/bin/bash #Filename: define.sh #Description: A Google define: frontend limit=0 if [ ! $# -ge 1 ]; then echo -e "Usage: $0 WORD [-n No_of_definitions]\n" exit -1; fi if [ "$2" = "-n" ]; then limit=$3; let limit++ fi word=$1 lynx -dump http://www.google.co.in/search?q=define:$word | \ awk '/Defini/,/Find defini/' | head -n -1 | sed 's:*:\n*:; s:^[ ]*::' | \ grep -v "[[0-9]]" | \ awk '{ if ( substr($0,1,1) == "*" ) { sub("*",++count".") } ; print } ' > /tmp/$$.txt echo if [ $limit -ge 1 ]; then cat /tmp/$$.txt | sed -n "/^1\./, /${limit}/p" | head -n -1 else cat /tmp/$$.txt; fi</pre> <pre>
Buscando enlaces rotos de una web
</pre> <pre>#!/bin/bash #Filename: find_broken.sh #Description: Find broken links in a website if [ $# -eq 2 ]; then echo -e "$Usage $0 URL\n" exit -1; fi echo Broken links: mkdir /tmp/$$.lynx cd /tmp/$$.lynx lynx -traversal $1 > /dev/null count=0; sort -u reject.dat > links.txt while read link; do output=`curl -I $link -s | grep "HTTP/.*OK"`; if [[ -z $output ]]; then echo $link; let count++ fi done < links.txt [ $count -eq 0 ] && echo No broken links found.</pre> <pre>
ssh con compresión
</pre> <pre>ssh -C user@host</pre> <pre>
¿ssh con zenity?
</pre> <pre>$ ssh username@remotehost 'export DISPLAY=:0 ; zenity --info --text "This</pre> <pre>
is a message"'
Lanzar un comando cada x segundos
</pre> <pre>watch -n 1 -d 'ls -l /tmp'</pre> <pre>
Mysqlcon bash
#!/bin/bash #Filename: read_db.sh #Description: Read from the database USER="user" PASS="user" depts=`mysql -u $USER -p$PASS students <