Posts Tagged ‘bash’

git: How to revert a file to a specific commit

This entry is part 7 of 7 in the series git: useful HOWTOs
git checkout COMMIT_HASH file/to/revert

Will bring the file/to/revert file to the state in COMMIT_HASH commit.

Pattern Matching Hyphen-Minus Sign in Bash

I was trying to use the sed command to perform some changes to a text and stepped into an interesting “problem”; pattern matching the minus-hyphen (-) symbol.

Assume we have the following text:

something
SoMeThiNg
some-thing
soMe_thing

and we want to match all the different versions of the word with one expression (one by one).

My initial idea was to use this regular expression:

's/[a-zA-Z\-\_]*/matched/'

Naturally, I tried to escape the – sign. As you can see from the output, this doesn’t work:

$ sed 's/[a-zA-Z\-\_]*/matched/' test 
matched
matched
matched-thing
matched

The minus sign is not matched, because of its special meaning (setting ranges). In order to make the expression work, you need to move the “-” either in the beginning or in the end of the expression:

$ sed 's/[a-zA-Z\_-]*/matched/' test 
matched
matched
matched
matched
$ sed 's/[-a-zA-Z\_]*/matched/' test 
matched
matched
matched
matched

and leave it un-escaped!

Selecting a random file/folder of a folder in Linux

I always had the following problem: “How to select which movie (from the ones in my collection) to watch“. In the past, I had used the random (pseudo-random to be precise) capabilities of C, Java, Erlang, and Javascript to select the movie.

Today I wrote a simple script that selects a random content (file or folder) within a folder:

#! /bin/sh
 
if [ $# -gt 0 ]; then
    cd "$1";
fi
 
ls -1 | awk 'BEGIN {srand()}
	{x[NR] = $0}
	END {print "Selected", x[1 + int(rand() * NR)]}'

Save it in a file (lets say srandom, make it executable:

$ chmod +x srandom

and execute it either with 0 or 1 arguments. Without an argument, the selection is done from the contents of the srandom‘s container, else the path given as an argument is used.

$ ./srandom.sh
Selected lrandom.html
$ ./srandom.sh /bin
Selected gzexe

Update

A much more elegant solution:

$ ls -1 | shuf -n1

Removing the SVN metadata files (.svn/) in Linux

If you ever want to remove a folder from SVN control (clean the folder by removing the .snv metadata folders) in Linux, you can simply run the following command:

rm -rf $(find path/to/the/CORRECT/folder -type d -name .svn)

where:

  • rm -rf is remove recursive force. Recursive for deleting the directories and their contents recursively and force for no prompting (for example, for write protected files)
  • $(..) is the command substitution, that takes the output of a command and uses it as input for another
  • find path/to/the/CORRECT/folder -type d -name .svn is searching (recursively) for folders (d for directory) with the name .svn1 in the directory pointed by path/to/the/CORRECT/folder

Be careful to use the correct path, else you can remove the svn metada for the wrong folder! A good approach can be to execute the find command without the rm, check the output, and then proceed to the remove :-).

1case sensitive, use -iname for insensitive

Extracting citations from a BibTex file using Linux terminal

I had a big (around 40 entries) BibTex file with the references of some papers I studied and I wanted to extract the citations in the format used for citing in Latex (\cite{AuthorYear}). Just today I read some tutorials about awk, so I thought “Let’s use it!!”.

An example BibTex file:

@article{Kotselidis2010,
author = {Kotselidis, Christos and Lujan, Mikel and Ansari, Mohammad and Malakasis,
    Konstantinos and Kahn, Behram and Kirkham, Chris and Watson, Ian},
doi = {10.1109/IPDPS.2010.5470460},
isbn = {978-1-4244-6442-5},
journal = {2010 IEEE International Symposium on Parallel \&
    Distributed Processing (IPDPS)},
pages = {1--12},
publisher = {Ieee},
title = {{Clustering JVMs with software transactional memory support}},
url = {http://ieeexplore.ieee.org/lpdocs/epic03/wrapper.htm?arnumber=5470460},
year = {2010}
}
@phdthesis{Zhang2009c,
author = {Zhang, Bo},
keywords = {cache-coherence,contention manager,distributed transactional memory},
title = {{On the Design of Contention Managers and Cache-Coherence Protocols for
    Distributed Transactional Memory}},
year = {2009}
}

Solution

awk 'BEGIN{FS="[{,]"} /@/ {print "\\cite{"$2"}"}' filename.bib

\cite{Zhang2009c}
\cite{Kotselidis2010}

In order to save the output in a file named cites.txt:

awk 'BEGIN{FS="[{,]"} /@/ {print "\\cite{"$2"}"}' filename.bib > cites.txt

Hint: Use “>>” if you want to append the output. Single > creates a new file (if not existing), or empties the existing one and then appends the content..

If you want to know my “implementation” process, continue reading 😉
Read the rest of this entry »

Really simple batch renaming in Linux

While working on the photos section of trigonakis.com, I wanted to batch rename some photos, so after the renaming their new name would be prefix_i, where i is a incremental value. The following (stupidly) simple bash script provides the desired functionality:

#!/bin/bash
 
INDEX=1
 
for i in *.$1; do
  echo item $INDEX: "$i" renamed to $2_$INDEX.$1
  mv "$i" $2_$INDEX.$1
  let INDEX=INDEX+1
done

Usage:

#make the script executable
chmod +x scriptname.sh
#move the folder containing the files to be renamed
mv from_path/scriptname.sh to_path/
#run the script
./scriptname.sh FILE_EXTENSION NAME_PREFIX
#example:
./rnm.sh JPG photo