Showing posts with label one-liner. Show all posts
Showing posts with label one-liner. Show all posts

2010-05-16

If you know it, you can...

I confess it: I often creep in forums and "ask your question" sites, sometimes I add my answers to solve a problem or manifest an idea (and often I think it's the best answers of course). Mostly it's boring but it is also a cheap pastime and I find it relaxing.

Few hours ago someone asked help for the following problem: I have a JPG file N kbytes long, and I want to make it M kbytes long (M > N). A typical trait of these questions is an almost total inability of the asker to express what they want in a non-ambiguous way.

The already written answers talked about increasing JPG quality and/or resizing image's width and height; these actions have as consequence to make the file bigger.

The common answerer focused on the fact that the file was an image (that can be resized) in a specific format the "quality" can be set of. Since the asker talked about file sizes, I focused on the file instead and swifly thought of cat and dd: dd can be used to "cut" a stream at the desired size, while cat allows the creation of a stream bigger than M. Since the simplest way to make a file bigger is to pad it with zeros, I thought of /dev/zero too, and wrote the line

cat file.jpg /dev/zero |
dd of=modified.jpg bs=1 count=800k


if we want the final file to be 800k bytes (800*1024) long. Neat and easy, isn't it? At this point someone can ask: but this way the JPG gets corrupted while the other answers have the merit not to waste it! And at this point it is useful a little bit of knowledge about JPG files: you can append data to a well-terminated JPG file without problem, since decoders stop to a marker which says the JPG file is finished. If you put data after the stop-marker, you do no harm.

The story taught me that a little bit of knowledge about file formats and classical "*nix" tools (in their GNU versions in my case) can solve a lot of problems easily, and that who does not know these things have as only option the use of softwares that do the job as needed; if there are not such softwares then you've not bricks you can build the solution with. If you don't have a bigger picture of what computers are for, your only idea will be to load you preferred image manipulation software and try to match the file size changing "parameters", and maybe you'll get it after several trial-error cycles... only to notice that now it looks different and you don't want it to look so different!!

So the suggestion is read read read read and learn learn learn learn (and install GNU coreutils:D)

And now a brief explanation of what the line does. cat A B concatenate two streams (e.g. two files) one after the other. The /dev/zero can be considered as a "virtual" infinite file made of all zero bytes. For this reason we need dd to select the right amount of bytes from the stream, copying to "output file" only the quantity we want (see e.g. this Wikipedia link about dd).

2010-05-06

Another lazy one-liner

Today I was back on twitter (guess, shintakezou) and found among people I am following an interesting link. I wanted to download almost everything and lazyly built the following line:

lynx http://address -dump |
egrep -v thumb |
egrep "[0-9]+\. http:" |
egrep "mp3|jpg" |sed -e 's/[0-9]\+\.//;s/^ \+//' |
xargs -n 1 wget


I am almost sure there's a better way, but I've just finished eating.

Since people may think this is mainly a p0rn scraping line (mixed with few good musical files), I claim it is not even though it could be used for that purpose too. In that address I've found many Bilibin images — I know this artist only because his paintings are often used on Fravia's site (R.I.P.) — and a mp3 file I am going to listen, the title is Nuclear weapons are morally infensible.

2010-03-30

One-liners and why to get it harder than it could be

Since I've updated kernel and X server, my computer became slower... new "softwares" require new hardware to do the same things. This is a fact that always upset me. Anyway, I abandoned KDE (unusable... and half-mixed KDE3-4!) and installed WindowMaker. I also abandoned full graphics file-manager (avoid the loading of Qt libs and KDE services, being used to use Konqueror, uncomparable to Dolphin), tried lightweight Gtk file-managers but none satisfied me. I used midnight commander for a while and tried also gnu-git ... But now mainly I use simply the command line, in a simple xterm of course...

So it happens that something easy and fast with a filemanager becomes a little bit harder. But still the command line, with all GNU tools around and interpreters of languages like perl, is powerful.

When I download pictures from the cam, I need renaming them according to EXIF date; so I've created a script (exifrename.sh), which uses exif the extract the date and rename the object the way I want. I use it like this

exifrename.sh *.jpg |bash


The pipe is because the script outputs the commands rather than executing them (it could be useful to check everything's fine).

My cam creates a directory for each day, like NUMcanon where NUM is a number not related to the day. What I want is to copy just some days, not all, into the local hard disk and in the same time I want to strip the "canon" part. It would be easier maybe to copy the dirs and then rename them. But less fun for me. So what I do is

for el in 101 102 105 ; do mkdir $el ; 
pushd $el ;
cp -r /media/usbpen/dcim/${el}canon/* . ;
popd ; done


Ok not so funny but useful to... Recently I had to convert several scattered .doc (alas Microsoft stuff) into HTML, I've used this

find . -iname "*.doc" |
(
while read line;
do wvHtml "$line" "${line%.doc}.html ; done
)


As last example, a "oneliner" to read FASTA headers / sequences and sort them (just the header). Don't ask why, I've found the request on Yahoo Answer.

perl -e '%p=();
while(<>) {
if (/^>/) {
s/^>//; chomp;
foreach $v (split("\x01", $_)) {
$p{$v} = 1 if !exists $p{$v} ;
}
}
}
print join(" ", sort keys %p)' <fasta.txt


A perl guru can make surely better (and what about perl6?), anyway the solution worked .

Now we discover that there are things that can't be done simply by a graphics interface but... These examples are taken directly from the history of the shell; there are other two similar examples. The history has 1045 entries. Of these, 1039 are mainly simple commands like cd, rm, cp, ls, mkdir (and sometimes mount and umount). Actions that would have been a lot easier using a graphical file manager!

So the problem said at the beginning is back: I need keeping running few processes/programs. ... I'm going to hate the computer business, because I can't see a reason why to do the same thing I did before now I need more memory or a more powerful processor... or downgrading the software (meaning I should compile by myself a lot of codes since oldest packaged pre-compiled programs are already too recent, or there are too many dependencies issues I don't want to cope with!)

I hope things will be better, but looking around I see things indeed get worse: we can say Berlusconi is the winner, and this means there's no hope to change for Italy (it seems OT, but is not...).



Ah, the exifrename.sh code:
for el in "$@"; do
pathpart=$( dirname "$el" )
namepart=$( basename "$el" )
data=$( exif "$el" |egrep "Date and Time \(orig" \
|sed -e 's/^.*|\([0-9]\{4\}\):\([0-9][0-9]\):\([0-9][0-9]\) \([0-9][0-9]\):\([0-9][0-9]\):.*$/\1\2\3-\4\5/' )
echo "mv \"$el\" \"$pathpart/$data-$namepart\""
done