1

I have bash shell script to modify string.

I want get 14040116 (YYMMDDHH) from string 44[tip] 3764d6b8ae82 2014-04-01 16:34 +0400 igor

My current script looks like

raw_info="44[tip] 3764d6b8ae82 2014-04-01 16:34 +0400 igor"

hg_date=`echo $raw_info | cut -d' ' -f 3`
hg_date=${hg_date//-/}
hg_date=${hg_date:2}
hg_hour=`echo $raw_info | cut -d' ' -f 4 | cut -d':' -f 1`

hg_rev=${hg_date}${hg_hour}

It works, but can it be shorter?

4 Answers 4

3

Here is an awk solution.

echo "44[tip] 3764d6b8ae82 2014-04-01 16:34 +0400 igor" | awk '{split($3,a,"-");split($4,b,":");print substr(a[1],3,2)a[2]a[3]b[1]}'
14040116
  • split($3,a,"-") divides the 3rd field by -, so 2014-04-01 gives a[1]=2014, a[2]=04, a[3]=01.
  • split($4,b,":")divides the 4th field by :, so 16:34 gives b[1]=16, b[2]=34.

Then print:

  • substr(a[1],3,2) gives last two digits of 2014, that is, 14.
  • a[2]a[3]b[1] gives 14040116.
Sign up to request clarification or add additional context in comments.

Comments

2

You can get the specific part of the string where the date is and then use date format controls to print it properly:

$ raw_info="44[tip] 3764d6b8ae82 2014-04-01 16:34 +0400 igor"
$ date -d"$(cut -d' ' -f3-4 <<< "$raw_info")" "+%y%m%d%H"
14040116

To store it into a variable, nest $():

$ hg_rev=$(date -d"$(cut -d' ' -f3-4 <<< "$raw_info")" "+%y%m%d%H")
$ echo "$hg_rev"
14040116

By pieces:

$ cut -d' ' -f3-4 <<< "$raw_info"   #get 3rd and 4th fields from the string
2014-04-01 16:34

$ date -d"2014-04-01 16:34" "+%y%m%d%H"  #convert date into YYMMDDHH format
14040116

as from man date:

   %y     last two digits of year (00..99)
   %m     month (01..12)
   %d     day of month (e.g., 01)
   %H     hour (00..23)

3 Comments

Any reason you're using cut here rather than PE?
...anyhow, ended up opting to add my own answer.
Ah, Parameter Expansion!
1

While (IMHO) @fedorqui's solution is the best, you can also employ sed, eg.

sed 's/.* \(2.\)\(..\)-\(..\)-\(..\) \(..\):.*/\2\3\4\5/' <<<"$raw_info"

what prints

14040116

Ps: it depends on two-digit format and 2xxx year

Comments

1

Every solution given thus far is invoking external commands, and thus needlessly inefficient.

The much more efficient approach is to use bash's built-in string manipulation tooling.

raw_info="44[tip] 3764d6b8ae82 2014-04-01 16:34 +0400 igor"
read -r tip_name hash ymd hour _ <<<"$raw_info"
hg_rev="${ymd:2:2}${ymd:5:2}${ymd:8:2}${hour%%:*}"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.