#TIL : Create a sequence of numbers

In the past, every time I want to create a sequence of numbers. I have to use something like MS EXCEL, then copy it and paste to text editor. It’s tricky way and slow !

Now, I can use the handy tool seq to achieve that

man seq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SEQ(1)                                          User Commands                                         SEQ(1)            

NAME
seq - print a sequence of numbers

SYNOPSIS
seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST

DESCRIPTION
Print numbers from FIRST to LAST, in steps of INCREMENT.

Mandatory arguments to long options are mandatory for short options too.

-f, --format=FORMAT
use printf style floating-point FORMAT

-s, --separator=STRING
use STRING to separate numbers (default: \n)

-w, --equal-width
equalize width by padding with leading zeroes

So we have 3 main arguments (same as for loop) :

  • FIRST
  • INCREMENT
  • LAST

And 3 options :

  • format : you can use string format like This is number %g
  • separetor : default is new line
  • equal width : padding with leading zeroes

Example :

1
2
3
4
5
6
$ seq -f"This is number %g" 3 4 20
This is number 3
This is number 7
This is number 11
This is number 15
This is number 19
1
2
$ seq -w -s", " 10
01, 02, 03, 04, 05, 06, 07, 08, 09, 10

#TIL : Cut file content from line to line

In case you have a big file which contains a lot of content (2+ GB). And you only need a small part from the file (the part is continuous string from line X to line Y).

You have many ways to achieve that :

  1. Use vi editor and delete from line 1 to line (X-1) by press [X-1]dd then go to line (Y-X+2) and delete to last line by press dG
  2. Use sed -n '[X][Y]p' [input_file] > [output_file]. Example : sed -n '15,68p' a.sql > b.sql
  3. Use head and tail trick : head -n[Y] [input_file] | tail -n[Y-X+1] > [output_file]

I personally recommend using the sed way, it’s faster and simpler to remember.

#TIL : Prepend line number to file

When you want to prepend line number in every line of file, use the -n flag of cat tool.

Example :

cat -n a.txt

Or even from many file

cat -n a.txt b.txt c.txt

#TIL : String problems can cause logical bugs in application

Example table

1
2
3
4
5
6
7
8
9
mysql> describe `test`;
+------------+-------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+-------------------+----------------+
| id | smallint(6) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| created_at | timestamp | YES | MUL | CURRENT_TIMESTAMP | |
+------------+-------------+------+-----+-------------------+----------------+
3 rows in set (0.00 sec)

Here is dump file of the table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (
`id` smallint(6) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

LOCK TABLES `test` WRITE;
/*!40000 ALTER TABLE `test` DISABLE KEYS */;

INSERT INTO `test` (`id`, `name`, `created_at`)
VALUES
(1,'abc','2017-02-16 17:28:59'),
(2,' ABC','2017-02-16 17:29:14'),
(3,'ABC ','2017-02-16 17:29:21'),
(4,'aBc','2017-02-16 17:29:31');

/*!40000 ALTER TABLE `test` ENABLE KEYS */;
UNLOCK TABLES;

Case Insensitive

When creating database, table and column, we have to set the default string COLLATION for them. And if we use collation end withs _ci, it means we ignore the Case Sensitive (or Case Insensitive).

Then "abc" == "ABC" or "abc" == "aBc" or "abc" = "Abc" or … (X = Y <=> UPPER(X) == UPPER(Y))

1
2
3
4
5
6
7
mysql> select ("abc" = "ABC") as `case1`, ("abc" = "aBc") as `case2`, ("abc" = "Abc") as `case3`, ("abc" = "abcd") as `wrong`;
+-------+-------+-------+-------+
| case1 | case2 | case3 | wrong |
+-------+-------+-------+-------+
| 1 | 1 | 1 | 0 |
+-------+-------+-------+-------+
1 row in set (0.00 sec)

String Trimming

Check this out !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test;
+----+-----------------+---------------------+
| id | name_with_quote | created_at |
+----+-----------------+---------------------+
| 1 | 'abc' | 2017-02-16 17:28:59 |
| 2 | ' ABC' | 2017-02-16 17:29:14 |
| 3 | 'ABC ' | 2017-02-16 17:29:21 |
| 4 | 'aBc' | 2017-02-16 17:29:31 |
+----+-----------------+---------------------+
4 rows in set (0.00 sec)

mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test where `name` = 'abc';
+----+-----------------+---------------------+
| id | name_with_quote | created_at |
+----+-----------------+---------------------+
| 1 | 'abc' | 2017-02-16 17:28:59 |
| 3 | 'ABC ' | 2017-02-16 17:29:21 |
| 4 | 'aBc' | 2017-02-16 17:29:31 |
+----+-----------------+---------------------+
3 rows in set (0.01 sec)

mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test where `name` = ' abc';
+----+-----------------+---------------------+
| id | name_with_quote | created_at |
+----+-----------------+---------------------+
| 2 | ' ABC' | 2017-02-16 17:29:14 |
+----+-----------------+---------------------+
1 row in set (0.00 sec)

BAAMMMMM !!!

holy-shit-the-illuminati-is-real

MySQL do right trimming the string value before comparing.

So you must be becareful to trim value before storing to MySQL to make everything consistent.

Storing Emoji in MySQL

Because Emoji use utf-8 4 bytes, so we must use the utf8mb4 charset (utf8 multi-bytes 4).

It’s safe when migrating charset from utf8 to utf8mb4 😎 , but not the reverse way 😅

#TIL : String Format Unicode params

1
2
unicode_thing = u"Xin chào mọi người"
a = '{}'.format(unicode_thing)

will cause the error UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 6: ordinal not in range(128)

The solution is add u prefix the pattern (it means using unicode pattern) :

1
2
unicode_thing = u"Xin chào mọi người"
a = u'{}'.format(unicode_thing)