Bad and Good Extraction with Regular Expressions in Perl

Again and again I find myself writing stuff like this:

if($str =~ /(\w+)\s+(\w+)(\s+(\w+))?/) {
      $result{id} = $1;
      $result{status} = $2;
      $result{details} = $4 if(defined($4));
}

when I should write:

if($str =~ /(?<id>\w+)\s+(?<status>\w+)(\s+(?<details>\w+))?/) {
      %result = %+;
}

as described in the perlre manual:

Capture group contents are dynamically scoped and available to you outside the pattern until the end of the enclosing block or until the next successful match, whichever comes first. (See Compound Statements in perlsyn.) You can refer to them by absolute number (using "$1" instead of "\g1" , etc); or by name via the %+ hash, using "$+{name}".

strptime() implementation in Javascript

If you need a simply strptime() implementation for Javascript feel free to use the following. I needed this for more sane date formatting in SpurTracer.

If you find this useful or find bugs please post a comment!

// Copyright (c) 2012 Lars Lindner <[email protected]>
//
// GPLv2 and later or MIT License - http://www.opensource.org/licenses/mit-license.php

var dayName = new Array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
var monthName = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dez");
   
/* simulates some of the format strings of strptime() */
function strptime(format, date) {
	var last = -2;
	var result = "";
	var hour = date.getHours();

	/* Expand aliases */
	format = format.replace(/%D/, "%m/%d/%y");
	format = format.replace(/%R/, "%H:%M");
	format = format.replace(/%T/, "%H:%M:%S");

	/* Note: we fail on strings without format characters */

	while(1) {
		/* find next format char */
		var pos = format.indexOf('%', last + 2);

		if(-1 == pos) {
			/* dump rest of text if no more format chars */
			result += format.substr(last + 2);
			break;
		} else {
			/* dump text after last format code */
			result += format.substr(last + 2, pos - (last + 2));

			/* apply format code */
			formatChar = format.charAt(pos + 1);
			switch(formatChar) {
				case '%':
					result += '%';
					break;
				case 'C':
					result += date.getYear();
					break;
				case 'H':
				case 'k':
					if(hour < 10) result += "0";
					result += hour;
					break;
				case 'M':
					if(date.getMinutes() < 10) result += "0";
					result += date.getMinutes();
					break;
				case 'S':
					if(date.getSeconds() < 10) result += "0";
					result += date.getSeconds();
					break;
				case 'm':
					if(date.getMonth() < 10) result += "0";
					result += date.getMonth();
					break;
				case 'a':
				case 'A':
					result += dayName[date.getDay() - 1];
					break;
				case 'b':
				case 'B':
				case 'h':
					result += monthName[date.getMonth()];
					break;
				case 'Y':
					result += date.getFullYear();
					break;
				case 'd':
				case 'e':
					if(date.getDate() < 10) result += "0";
					result += date.getDate();
					break;
				case 'w':
					result += date.getDay();
					break;
				case 'p':
				case 'P':
					if(hour < 12) {
						result += "am";
					} else {
						result += "pm";
					}
					break;
				case 'l':
				case 'I':
					if(hour % 12 < 10) result += "0";
					result += (hour % 12);
					break;
			}
		}
		last = pos;
	}
	return result;
}

Follow file with tail until it gets removed...

Instead of

tail -f /var/log/myserver.log

use

tail --follow=name /var/log/myserver.log

Using the long form --follow instead of -f you can tell tail to watch the file name and not the file descriptor. So shortly after the file name was removed tail will notice it and terminate itself.

GCC linking and mixed static and dynamic linking

GCC syntax schema to link some libraries statically and others dynamically:

gcc <options> <sources> -o <binary> -Wl,-Bstatic <list of static libs> -Wl,Bdynamic <list of dynamic libs>

Regex in Postgres UPDATE Statement

Want to use regular expressions in Postgres UPDATE statements?


BEGIN;
UPDATE table SET field=regexp_replace(field, 'match pattern', 'replace string', 'g');
END;

Why nm-applet does not show up...

When search online for answers on how the Network Manager doesn't show up in the GNOME notification area one find hundreds of confused forum posts (mostly Ubuntu).

There are only two reasons:

  1. Your Network Manager setup is somehow broken
  2. There is no network device to manage

The second case is propably going on in most of the cases. When you check your /etc/network/interfaces and see something like:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

... it cannot work, as Network Manager to manage your connections it needs to look like:

auto lo
iface lo inet loopback

Restart Network Manager (e.g. "/etc/init.d/network-manager restart") for the nm-applet icon to show up.

pgbouncer "Pooler Error: Auth failed"

If connections to your pgbouncer setup fail with "Pooler Error: Auth failed" check the following configuration values in your pgbouncer.ini

  • auth_file = ... : Ensure to point this path to your pg_auth file in your Postgres setup.
  • auth_type = ... : Ensure to set the correct authentication type. E.g. "md5" for MD5 hashed passwords.
  • Check if your pg_auth file has the needed passwords entries.

libfaac 1.28 compilation fails with: mpeg4ip.h:126:58: error: new declaration ‘char* strcasestr(const char*, const char*)’

When compiling libfaac with GCC you get:

g++ -DHAVE_CONFIG_H -I. -I../.. -I../../include -Wall -g -O2 -MT 3gp.o -MD -MP -MF .deps/3gp.Tpo -c -o 3gp.o 3gp.cpp
In file included from mp4common.h:29:0,
from 3gp.cpp:28:
mpeg4ip.h:126:58: error: new declaration ‘char* strcasestr(const char*, const char*)’
/usr/include/string.h:369:28: error: ambiguates old declaration ‘const char* strcasestr(const char*, const char*)’
make[3]: *** [3gp.o] Error 1

Solution is to remove the declaration of strcasestr() in commom/mp4v2/mpeg4ip.h (suggested here).

ffmpeg AAC "Can not resample 6 channels..."

When you try to encode with ffmpeg and you end up with such an error

Resampling with input channels greater than 2 unsupported.
Can not resample 6 channels @ 48000 Hz to 6 channels @ 48000

you are probably trying to encode from AAC with 5.1 audio to less than 6 channels or different audio sampling rate.

There are three solutions:

  1. As a solution either do not reduce the audio channels and change the audio sampling rate or do convert the audio with faad first.
  2. Apply one of the available ffmpeg patches to fix the AAC 6 channel issue...
  3. Split video and audio and convert audio separately.

The third solution can be done as following:

  1. Extract audio with ffmpeg:
    ffmpeg -y -i source.avi -acodec copy source.6.aac
  2. Convert audio with faad:
    faad -d -o source.2.pcm source.6.aac
  3. Merge video and audio again with ffmpeg:
    ffmpeg -y -i source.avi -i source.2.pcm -map 0:0 -map 1:0 -vcodec copy -acodec copy output.avi

Update: As hinted by a fellow commenter the big disadvantage is the quality loss as faad can only convert into PCM 16bit.

Fix Broken Text Encoding

You have a text file with broken encoding? You want to strip it from all invalid characters?

Here is how to do it:

iconv -c -t ASCII input.txt

The result will be printed to stdout. The -c switch does the stripping. Using -t you can select every target encoding you like.

Syndicate content Syndicate content