Find palindrome dates in the Linux command line - explained

栏目: IT技术 · 发布时间: 6年前

内容简介:Yesterday I saw aThe command was posted on Twitter byIn this post we are going to break it down and explain how it works.

Yesterday I saw a great command that finds the palindrome dates between now and x days ago.

The command was posted on Twitter by @climagic (a great account to follow if you want to find awesome command line stuff).

In this post we are going to break it down and explain how it works.

What is a palindrome

Palindrome is a word/number/phrase or other sequence of characters that reads the same backward as forward. Palindrome - Wikipedia

Few days ago, the date was 02/02/2020 which was a palindrome:

Find palindrome dates in the Linux command line - explained

The command

printf "now - %d days\n" {1..332044} |date -f- +%Y%_m%_d$'\n'%Y%m%d |tr -d ' ' > alldates.txt; rev alldates.txt >revdates.txt; paste alldates.txt revdates.txt |awk '$1==$2{print $1}'

And here’s a more readable version using new lines after each pipe.

printf "now - %d days\n" {1..332044} |
date -f- +%Y%_m%_d$'\n'%Y%m%d |
tr -d ' ' > alldates.txt; rev alldates.txt >revdates.txt; paste alldates.txt revdates.txt |
awk '$1==$2{print $1}'

I am going to explain each part of the command separately.

Note that the output of each part is the input of the next part (following the pipe | ).

printf "now - %d days\n" {1..332044}

The first part seems pretty straight forward but it does have an interesting part, the brace expansion mechanism , which I didn’t know of.

Open a terminal and type the following commands:

# From 1 to 10
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

# From a to z
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

# From 10 to 20
$ echo Before-{10..20}-After
Before-10-After Before-11-After Before-12-After Before-13-After Before-14-After Before-15-After Before-16-After Before-17-After Before-18-After Before-19-After Before-20-After

As you can see, the brace expansion allows the generation of values based on a “sequence” we set.

Learn more about the Brace expansion mechanism here .

Part explained

{1..332044}

Output

now - 1 days
now - 2 days
now - 3 days
now - 4 days
now - 5 days
...
now - 332038 days
now - 332039 days
now - 332040 days
now - 332041 days
now - 332042 days
now - 332043 days
now - 332044 days

date -f- +%Y%\_m%\_d$'\n'%Y%m%d

In this part we use the date command to parse the previously piped output and print two lines for each date, one with padding zeros and one without zeros for single digit days and months.

Familiarize yourself with the command in your terminal:

# Show current date = now
$ date
Thu Feb  6 07:30:10 EET 2020

# Show yesterday
$ date --date="now - 1 days"
Wed Feb  5 07:31:22 EET 2020

# Show yesterday as dd/mm/yyyy (zero padding)
$ date --date="now - 1 days" +%d/%m/%Y
05/02/2020

# Show yesterday as dd/mm/yyyy (space padded)
$ date --date="now - 1 days" +%_d/%_m/%Y
 5/ 2/2020

# Show yesterday as dd/mm/yyyy (without padding)
$ date --date="now - 1 days" +%-d/%-m/%Y
5/2/2020

Part explained

  • we use the -f option to define the input of the date to be the lines of a file, followed by a hyphen - to set this file to be the stdin
  • we set the output format (what follows the plus + symbol) to be the numeric representation of the year ( %Y ), the month (padded with spaces: %_m , padded with zeros: %m ) and the day of the month (padded with spaces: %_d , padded with zeros: %d )
  • the space padded format is %Y%\_m%\_d and the zero padded format is %Y%m%d
  • we combine these two formats for each date and we separate them with a new line $'\n' thus, for each date we parse, we produce two lines, one padded with zeros and one padded with spaces

Note: instead of padding with spaces (using the underscore _ in the format), we could use the hyphen - instead which would skip the padding of the field . This way wouldn’t have to remove the spaces as described in the next part.

Output

tr -d ' ' > alldates.txt; rev alldates.txt >revdates.txt; paste alldates.txt revdates.txt

In this part we remove the spaces produced in the previous step and we create two files, one with all the dates and one with all the dates reversed.

Then we combine these two files by merging each line of the first file with the corresponding line of the second file separated with a tab.

Familiarize your self with the commands of this part in your terminal:

# Remove empty spaces
$ echo "Good night " | tr -d " "
Goodnight

# Remove hyphens
$ echo "Good-night" | tr -d "-"
Goodnight

# Print a-x-z where x is a number between 1 and 9
$ printf "a-%d-z\n" {1..9}
a-1-z
a-2-z
a-3-z
a-4-z
a-5-z
a-6-z
a-7-z
a-8-z
a-9-z

# and then reverse the order of the characters of each line
$ printf "a-%d-z\n" {1..9} | rev
z-1-a
z-2-a
z-3-a
z-4-a
z-5-a
z-6-a
z-7-a
z-8-a
z-9-a

Part explained

  • tr -d '' : we remove the spaces of the input (which is the output of the previous part) and we save the output in a file named alldates.txt
  • rev : we reverse the order of the characters of each line of the alldates.txt file and we save the output in a new file named revdates.txt
  • paste : we merge the two files; each line of the alldates.txt file is merged with the corresponding line of the file revdates.txt separated by a tab (the two files have the exact number of lines).

Output

awk '$1==$2{print $1}'

In this final part, we use awk to print the palindromes.

Familiarize yourself with the usage of awk related to this post, in your terminal:

# Print the whole input (awk's default behavior) if the fields are equal
$ echo "a a" | awk '$1==$2'
a a

# Print the whole input (awk's default behavior) if the fields are not equal
$ echo "a a" | awk '$1!=$2'
# nothing here

# Print the whole input (awk's default behavior) if the fields are not equal
$ echo "a b" | awk '$1!=$2'
a b

# Print the first field (awk's default behavior) if the fields are not equal
$ echo "a b" | awk '$1!=$2 {print $1}'
a

# Print the second field (awk's default behavior) if the fields are not equal
$ echo "a b" | awk '$1!=$2 {print $2}'
b

Part explained

  • the previous output that is now the input of this part consists of lines and each line has two values separated by a TAB. With this kind of input, awk resolves two fields in each line. We can access these two fields using the $1 and $2 variables.
  • as described in aprevious post, awk statements consist of a pattern-expression and an associated action.
    <pattern/expression> { <action> }

    If the pattern succeeds then the associated action is being executed. In this part the expression is translated as “if the two fields are equal” ( $1==$2 ) and the action as “print the first field” ( printf $1 ).

  • if the fields are equal we do have a palindrome since each pair of fields is actually a date and its reversed value.

Output

20200202
2019102
2018102
2017102
2016102
2015102
2014102
2013102
2012102
...
11111111
11111111
1111111
1111111
111111

Cat photo

That’s all, thanks for reading.

Find palindrome dates in the Linux command line - explained

References


以上所述就是小编给大家介绍的《Find palindrome dates in the Linux command line - explained》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Processing语言权威指南

Processing语言权威指南

Casey Reas、Ben Fry / 张静 / 电子工业出版社 / 2013-10-1 / 139.00

本书介绍了可视化艺术中的计算机编程概念,对开源编程语言Processing作了非常详尽的阐述。学生、艺术家、设计师、建筑师、研究者,以及任何想编程实现绘画、动画和互动的人都可以使用它。书中的大部分章节是短小的单元,介绍Processing的语法和基本概念(变量、函数、面向对象编程),涵盖与软件相关的图像处理、绘制,并且给出了大量简短的原型程序,配以相应的过程图像与注释。书中还有一些访谈文章,与动画......一起来看看 《Processing语言权威指南》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具