Conversion of date format using sed or awk - date

I am new to unix and i am searching for an answer for the below problem.
I have a semi colon delimited file as below
Frank;01012019;01012020;woodcrest wack st
Mark;01012019;01012020;Annunciation st
Fred;01022019;01012020;Baker st
The date format in the input file is in DDMMYYYY format. I need the date to be converted into YYYYMMDD format as below.
Expected Output:
Frank;20190101;20200101;woodcrest wack st
Mark;20190101;20200101;Annunciation st
Fred;20190201;20200101;Baker st
Please suggest me answers using sed or awk command.

With GNU sed:
sed -r 's/;([0-9]{2})([0-9]{2})([0-9]{4})/;\3\2\1/g' file.csv
Output:
Frank;20190101;20200101;woodcrest wack st
Mark;20190101;20200101;Annunciation st
Fred;20190201;20200101;Baker st

awk -F';' '{print $1";"substr($2, 5, 4)""substr($2, 1, 2)""substr($2, 0, 2)";"substr($3, 5, 4)""substr($3, 1, 2)""substr($3, 0, 2)";"$4}' file

sed -E 's/([0-9]{2})([0-9]{2})([0-9]{4});/\3\2\1;/g' data
#=> Frank;20190101;20200101;woodcrest wack st
#=> Mark;20190101;20200101;Annunciation st
#=> Fred;20190201;20200101;Baker st
\1, \2, and \3 represent each parenthesis catched content, i.e. the DD, MM, and YYYY here. s is to replace in sed.
The g at last means to replace all occurances, without it sed will only replace first group.
If the input is formatted and stable like you said, then sed is actually easier to do this.
ps: -E is for extended regular expressions, it works both on unix sed and GNU sed.
It relieves you the needs to escape (){}.

With Perl
$ cat sadhiya.txt
Frank;01012019;01012020;woodcrest wack st
Mark;01012019;01012020;Annunciation st
Fred;01022019;01012020;Baker st
$ perl -F";" -lane ' s/(.{2})(.{2})(.{4})/$3$2$1/g for #F[1..2]; print join(";",#F) ' sadhiya.txt
Frank;20190101;20200101;woodcrest wack st
Mark;20190101;20200101;Annunciation st
Fred;20190201;20200101;Baker st

With sed:
sed -E -n 's/(.*);([0-9]{2})([0-9]{2})([0-9]{4});([0-9]{2})([0-9]{2})([0-9]{4});(.*)/\1;\4\3\2;\7\6\5;\8/p' file_name

Related

Replace duplicate character after first pattern

With this data
aaa:
- bbbb: ccc ddd' {eeee [fff
kkk: mmm nnn" oo pp
I like to have removed all duplicate spaces after the first :
aaa:
- bbbb: ccc ddd' {eeee [fff
kkk: mmm nnn" oo pp
Using \b doesn't help here.
With perl (assuming there's only one : per line):
$ perl -pe 's/ +(?!.*:)/ /g' ip.txt
aaa:
- bbbb: ccc ddd' {eeee [fff
kkk: mmm nnn" oo pp
If you can have multiple : but you still want to squeeze multiple spaces after the first :, you can use this:
perl -pe 's/^[^:]+(*SKIP)(*F)| +/ /g'
With sed:
$ sed -E ':a s/^([^:]+:.*) {2,}/\1 /; ta' ip.txt
aaa:
- bbbb: ccc ddd' {eeee [fff
kkk: mmm nnn" oo pp
:a is a label for the substitute command. As long as a match is found, ta will jump to the label, thus replacing all possible matches.
This might work for you (GNU sed):
sed -E ':a;s/(^[^:]*:( \S+)*) +/\1 /;ta' file
Match on two or more spaces following a : and replace by a single space, then repeat until no more matches.
Alternative:
sed -E ':a;s/(^[^:]*:[^ ]*) +/\1\n/;ta;y/\n/ /' file
Replace all space or spaces after a : with a newline and repeat until no more matches. Then translate all newlines to spaces (newlines are never present in the pattern space unless the user places them there).

Replace pattern in specific column in sed

I have a tab file with two columns like below
BB_12 100_AA
BB_13 101_AB
BB_14 102_AD
BB_15 103_AC
I wish to remove the number_ in second column (replace number_ with nothing). For this I tried sed replace in the following ways unsuccessfully.
sed 's/\d+\_//g' infile
sed 's/(\d+\_)//g' infile
But none of the tweaks worked. It looks like it is not searching in 2nd column. How to modify this ? The expected output is
BB_12 AA
BB_13 AB
BB_14 AD
BB_15 AC
Thanks in advance.
You may just process the last column with sed:
sed -E 's/[^ ]*_([^ ]*) *$/\1/' file
The output:
BB_12 AA
BB_13 AB
BB_14 AD
BB_15 AC
Awk alternative:
awk '{ sub(/^[^ ]+_/, "", $2) }1' OFS='\t' file
Following simple sed may help you in same.
sed 's/\([^ ]*\) \([^_]*\)_\(.*\)/\1 \3/g' Input_file
Output will be as follows.
BB_12 AA
BB_13 AB
BB_14 AD
BB_15 AC

Unix - Removing everything after a pattern using sed

I have a file which looks like below:
memory=500G
brand=HP
color=black
battery=5 hours
For every line, I want to remove everything after = and also the =.
Eventually, I want to get something like:
memory:brand:color:battery:
(All on one line with colons after every word)
Is there a one-line sed command that I can use?
sed -e ':a;N;$!ba;s/=.\+\n\?/:/mg' /my/file
Adapted from this fine answer.
To be frank, however, I'd find something like this more readable:
cut -d = -f 1 /my/file | tr \\n :
Here's one way using GNU awk:
awk -F= '{ printf "%s:", $1 } END { printf "\n" }' file.txt
Result:
memory:brand:color:battery:
If you don't want a colon after the last word, you can use GNU sed like this:
sed -n 's/=.*//; H; $ { g; s/\n//; s/\n/:/g; p }' file.txt
Result:
memory:brand:color:battery
This might work for you (GNU sed):
sed -i ':a;$!N;s/=[^\n]*\n\?/:/;ta' file
perl -F= -ane '{print $F[0].":"}' your_file
tested below:
> cat temp
abc=def,100,200,dasdas
dasd=dsfsf,2312,123,
adasa=sdffs,1312,1231212,adsdasdasd
qeweqw=das,13123,13,asdadasds
dsadsaa=asdd,12312,123
> perl -F= -ane '{print $F[0].":"}' temp
abc:dasd:adasa:qeweqw:dsadsaa:
My command is
First step:
sed 's/([a-z]+)(\=.*)/\1:/g' Filename |cat >a
cat a
memory:
brand:
color:
battery:
Second step:
sed -e 'N;s/\n//' a | sed -e 'N;s/\n//'
My output is
memory:brand:color:battery:

Brocade alishow merge two consecutive lines awk sed

How would like to join two lines usung awk or sed?
For example, I have data like below:
abcd
12:12:12:12:12:12:12:12
efgh001_01
45:45:45:45:45:45:45:45
ijkl7464746
78:78:78:78:78:78:78:78
and I need output like below:
abcd 12:12:12:12:12:12:12:12
efgh001_01 45:45:45:45:45:45:45:45
ijkl7464746 78:78:78:78:78:78:78:78
Running this almost works, but I need the space or tab:
awk '!(NR%2){print$0p}{p=$0}'
You're almost there:
awk '(NR % 2 == 0) {print p, $0} {p = $0}'
With sed you can do that as follows:
sed -n 'N;s/\n/ /p' file
where:
N reads next line
s replaces the new line character with a space to join both lines properly
p prints the result
This might work for you:
sed '$!N;s/\n/ /' file
or this:
paste -sd' \n' file

Printing next line with sed

I want to print next line of matching word with sed.
I tried this command but it gives error :
sed -n '/<!\[CDATA\[\]\]>/ { N p}/' test.xml
what about grep -e -A 1 regex? It will print line below regex.
With sed, looking for pattern "dd", below works fine as you would:
sed -n '/dd/ {n;p}' file
For file content:
dd
aa
ss
aa
It prints:
aa
use awk
awk '/pattern/{getline;print}' file