Gitlab CI variable issue extracting subgroup path for Pages - sed

I am trying to extract the Gitlab Pages path for my subgroup project.
The CI_PAGES_URL variable is https://mygroup.gitlab.io/subgroup/project/. I used the following script to extract the path:
echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\3#g'
In my local environment, everything seems fine:
> export CI_PAGES_URL=https://mygroup.gitlab.io/subgroup/project/
> echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\3#g'
/subgroup/project/
But in the Gitlab CI environment, things didn't go as expected:
> echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\3#g'
/project/
Naturally, I've checked other submatches:
> echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\1#g'
https
> echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\2#g'
mygroup.gitlab.io/subgroup
> echo $CI_PAGES_URL | sed -E 's#^(http|https)://([[:alnum:]\.\-\_]+)(/.+)$#\3#g'
/project/
I've checked the sed version. Both the CI and my local environment are using GNU sed 4.4.
What is going on?

Turns out this fixed my problem. And I still have no idea why there is a difference between my local environment and the CI. But there you have it:
echo "$CI_PAGES_URL" | sed -E 's#^(http|https)://([[:alnum:]\.-\_]+?)(/.+)$#\3#g'
There are 2 changes:
Quoted the variable $CI_PAGES_URL.
Added the lazy qualifier ? to the domain name match (\2).

Related

How would I generate list of dates and git commits?

I wrote some code that generates a github contributions-style heatmap in the terminal given a csv file that contains timestamps and some unsigned value.
I'd like to generate a csv that contains dates and the number of github contributions I made on that date.
Is there a simple way to do this?
You could use git log and a custom format:
git log --date=short --format="%an %ad [%h] %s" | cut -d ' ' -f1 -f2 -f3 -f4- | sed -E 's/ /,/' | sed -E 's/ /,/' | sed -E 's/ /,/'
I get:
Lachlan,Miller,2019-03-25,[e20b847] Rename method
Lachlan,Miller,2019-03-25,[6c47dbf] Add a POC using JS
lmiller1990,2018-04-12,[c295307],Add song class
lmiller1990,2018-04-12,[876cbe2],Add timer
You could use grep for this job. Also, flags like i, A and color will help you cleaning things up a bit. Also, output the result in a .csv file using >
use man grep to know a more about its flags.
Try using:
git log | grep -E -A 2 --color "commit|Date" > output.csv
You could also add --summary flag to log.

How to remove after second period in a string using sed

In my script, have a possible version number: 15.03.2 set to variable $STRING. These numbers always change. I want to strip it down to: 15.03 (or whatever it will be next time).
How do I remove everything after the second . using sed?
Something like:
$(echo "$STRING" | sed "s/\.^$\.//")
(I don't know what ^, $ and others do, but they look related, so I just guessed.)
I think the better tool here is cut
echo '15.03.2' | cut -d . -f -2
This might work for you (GNU sed):
sed 's/\.[^.]*//2g' file
Remove the second or more occurrence of a period followed by zero or non-period character(s).
$ echo '15.03.2' | sed 's/\([^.]*\.[^.]*\)\..*/\1/'
15.03
More generally to skip N periods:
$ echo '15.03.2.3.4.5' | sed -E 's/(([^.]*\.){2}[^.]*)\..*/\1/'
15.03.2
$ echo '15.03.2.3.4.5' | sed -E 's/(([^.]*\.){3}[^.]*)\..*/\1/'
15.03.2.3
$ echo '15.03.2.3.4.5' | sed -E 's/(([^.]*\.){4}[^.]*)\..*/\1/'
15.03.2.3.4

Ansible command quotes

I would like to have the following command integrated in an Ansible playbook task:
cut -f 1 -d: /etc/passwd | xargs -n 1 -I {} bash -c ' echo -e "\n{}" ; chage -l {}'.
Any quote inside breaks the whole command. How I can avoid it to make it run the whole string?
Many thanks in advance.
You can simply use the YAML literal block string syntax. In that way you don't need to escape any quotes. Instead, you can pass your shell command as is.
Example:
- name: test task
shell:
cmd: |
cut -f 1 -d: /etc/passwd | xargs -n 1 -I {} bash -c ' echo -e "\n{}" ; chage -l {}'
tags: test
You can escape them with \”
example: "hello=\"hi\""

Sed not matching one or more patterns

I have this list of files:
$ more files
one_this_2017_1_abc.txt
two_that_2018_1_abc.txt
three_another_2017_10.abc.txt
four_again_2018_10.abc.txt
five_back_2018_1a.abc.txt
I would like to get this output:
one_this_XXXX_YY_abc.txt
two_that_XXXX_YY_abc.txt
three_another_XXXX_YY.abc.txt
four_again_XXXX_YY.abc.txt
five_back_XXXX_YY.abc.txt
I am trying to remove the year and the bit after the year and replace them with another string--this is to generate test cases.
I can get the year just fine, but it's that one or two character piece after it I can't seem to match.
This should work, right?
~/test_cases
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[[:alnum:]]\{1,2\}_/_YY_/'
one_this_XXXX_YY_abc.txt
two_that_XXXX_YY_abc.txt
three_another_XXXX_10.abc.txt
four_again_XXXX_10.abc.txt
five_back_XXXX_1a.abc.txt
Except it doesn't for the 2 character cases.
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[[:alnum:]]\
{2\}_/_YY_/'
one_this_XXXX_1_abc.txt
two_that_XXXX_1_abc.txt
three_another_XXXX_10.abc.txt
four_again_XXXX_10.abc.txt
five_back_XXXX_1a.abc.txt
Doesn't work for the two character cases either, and this works not at all (but according to the docs it should):
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[[:alnum:]]\+_/_YY_/'
one_YY_XXXX_1_abc.txt
two_YY_XXXX_1_abc.txt
three_YY_XXXX_10.abc.txt
four_YY_XXXX_10.abc.txt
five_YY_XXXX_1a.abc.txt
Other random experiments that don't work:
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[a-zA-Z0-9]\+_/_YY_/'
one_YY_XXXX_1_abc.txt
two_YY_XXXX_1_abc.txt
three_YY_XXXX_10.abc.txt
four_YY_XXXX_10.abc.txt
five_YY_XXXX_1a.abc.txt
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[a-zA-Z0-9]\{1\}_/_YY_/'
one_this_XXXX_YY_abc.txt
two_that_XXXX_YY_abc.txt
three_another_XXXX_10.abc.txt
four_again_XXXX_10.abc.txt
five_back_XXXX_1a.abc.txt
$ cat files | sed -e 's/_[[:digit:]]\{4\}_/_XXXX_/' -e 's/_[a-zA-Z0-9]\{2\}_/_YY_/'
one_this_XXXX_1_abc.txt
two_that_XXXX_1_abc.txt
three_another_XXXX_10.abc.txt
four_again_XXXX_10.abc.txt
five_back_XXXX_1a.abc.txt
Tried with both GNU sed version 4.2.1 under Linux and sed (GNU sed) 4.4 under Cygwin.
And yes, I realize I can pipe this through multiple sed calls to get it to work, but that regex SHOULD work, right?
if your Input_file is same as shown sample then following may help you in same.
sed 's/\([^_]*\)_\([^_]*\)_\(.*_\)\(.*\)/\1_\2_XXXX_YY_\4/g' Input_file
Output will be as follows.
one_this_XXXX_YY_abc.txt
two_that_XXXX_YY_abc.txt
three_another_XXXX_YY_10.abc.txt
four_again_XXXX_YY_10.abc.txt
five_back_XXXX_YY_1a.abc.txt

How to determine date/time when a file was first added to CVS repository

Is there any simple cvs command through which I can get date/time when a file was first added to the module in CVS repository.
I actually want a one line output that can be consumed by my some script.
This is not directly possible in CVS. One can get activity logs for a file and then identify the date from them. Following is the single line command that works like a charm and gives the date when the file was first added in the repository.
cvs -Q -d :pserver:*User*:*Pass*#*HostName*:/cvsroot rlog -N *FilePath* | grep ^date: | sort | head -n 1 | cut -d\; -f1 | sed -e 's/date: //'
Above command looks through the entire repository and gives the date. If one is looking for first activity on that file on a branch use following commands.
For Branch:
cvs -Q -d :pserver:*User*:*Pass*#*HostName*:/cvsroot rlog -N -r*BranchName* *FilePath* | grep ^date: | sort | head -n 1 | cut -d\; -f1 | sed -e 's/date: //'
For Trunk:
cvs -Q -d :pserver:*User*:*Pass*#*HostName*:/cvsroot rlog -N -r::HEAD *FilePath* | grep ^date: | sort | head -n 1 | cut -d\; -f1 | sed -e 's/date: //'