changing the date formatin linux bash - linux

Regarding an earlier answer, I need to change the date format from yyyy-mm-dd to yyyy/mm/dd.
I was given this answer:
sed -i 's#,\(....\)-\(..\)-\(..\) #,\1/\2/\3 #' /home/Documents/blah.csv
this works perfectly, for only one instance per line. However one line can have many of these dates, how do I change the sed command so it does it for every instance detected (not just the first).
Example document:
2012-09-09,123143,2012-09-09,12837,2012-09-07,2131,2012-08-06,1237
#and many more lines like that.
after running the sed command, I get this:
2012-09-09,123143,2012/09/09,12837,2012-09-07,2131,2012-08-06,1237
It only works on the second date instance, How do i make it work for all of them?

Use the g flag, to make substitutions for every match in a line, not just the first. Also, the first date isn't matched because it isn't preceded by a comma.
sed -i 's#\(....\)-\(..\)-\(..\)#\1/\2/\3/#g' /home/Documents/blah.csv
This fixes a few issues:
Don't bother matching the commas; the 4-2-2 nature of the data should be sufficient, and the first field is not matched because it isn't preceded by a comma.
Add the g flag following the terminating # to replace all matches, not just the first.
Added a forgotten / between the year (\1) and the month (\2).

Related

linux shell script delimiter

How to change delimiter from current comma (,) to semicolon (;) inside .txt file using linux command?
Here is my ME_1384_DataWarehouse_*.txt file:
Data Warehouse,ME_1384,Budget for HW/SVC,13/05/2022,10,9999,13/05/2022,27,08,27,08
Data Warehouse,ME_1384,Budget for HW/SVC,09/05/2022,10,9999,09/05/2022,45,58,45,58
Data Warehouse,ME_1384,Budget for HW/SVC,25/05/2022,10,9999,25/05/2022,7,54,7,54
Data Warehouse,ME_1384,Budget for HW/SVC,25/05/2022,10,9999,25/05/2022,7,54,7,54
It is very important that value of last two columns is number with 2 decimal places, so value of last 2 columns in first row for example is:"27,08"
That could be the main problem why delimiter couldn't be change in proper way.
I tried with:
sed 's/,/;/g' ME_1384_DataWarehouse_*.txt
and every comma sign has been changed, including mentioned value of the last 2 columns.
Is there anyone who can help me out with this issue?
With sed you can replace the nth occurrence of a certain lookup string. Example:
$ sed 's/,/;/4' file
will replace the 4th comma with a semicolon.
So, if you know you have 11 fields (10 commas), you can do
$ sed 's/,/;/g;s/;/,/10;s/;/,/8' file
Example:
$ seq 1 11 | paste -sd, | sed 's/,/;/g;s/;/,/10;s/;/,/8'
1;2;3;4;5;6;7;8,9;10,11
Your question is somewhat unclear, but if you are trying to say "don't change the last comma, or the third-to-last one", a solution to that might be
perl -pi~ -e 's/,(?![^,]+(?:,[^,]+,[^,]+)?$)/;/g' ME_1384_DataWarehouse_*.txt
Perl in isolation does not perform any loop over the input lines, but the -p option says to loop over input one line at a time, like sed, and print every line (there is also -n to simulate the behavior of sed -n); the -i~ says to modify the file, but save the original with a tilde added to its file name as a backup; and the regex uses a negative lookahead (?!...) to protect the two fields you want to exempt from the replacement. Lookaheads are a modern regex feature which isn't supported by older tools like sed.
Once you are satisfied with the solution, you can remove the ~ after -i to disable the generation of backups.
You can do this with awk:
awk -F, 'BEGIN {OFS=";"} {a=$NF;NF-=1; printf "%s,%s\n",$0,a} ' input_file
This should work with most awk version (do not count on Solaris standard awk)
The idea is to store the last element from row in variable, decrease the number of fields and then print using new delimiter, comma and stored last field.

Insert characters before a line that contains numbers

Given a text file with lines (for example, a file with three sentences, it will be three lines).
It is necessary in the lines where there are numbers to add the current time in front of them (lines).
By inserting the current time, I sort of figured it out:
sed "s/^/$(date +%T) /" text.txt
I saw it but it doesn't suit me as it is here used IF
But how can I make the strings also be checked for the presence of digits?
But how to check a string for numbers and insert a date before it with one command?
It is possible without
if
statement?
You can use a regex to match the lines
sed "/[0-9]/s/^/$(date +%T) /" text.txt

unix command to replace anything between between two delimiter positions

Please help me with a unix command to replace anything between two delimiter positions.
For ex: I have multiple files with below header data and I want replace the data between * delimiters at 9th and 10th position
ISA*00* *00* *ZZ*80881 *ZZ*TNC0022 *190115*1237*^*00501*000320089*0*P*|~
My output should like this:
ISA*00* *00* *ZZ*80881 *ZZ*TNC0022 *190327*1237*^*00501*000320089*0*P*|~
Try this:
perl -pe 's/^((?:[^*]*\*){9})([^*]+)(.*)/${1}190327$3/'
The regexp searches for 9 occurences {9} of anything but not being a star [^*] followed by a star \* and stores all in the first capture group. The second capture is at least one character not being a star [^*]+. And the third capture is the rest of the line.
A matching line gets replaced by the first part ${1}, your new value 190327 and the third part $3.

Replace value in string

I have text file with ~70k lines like this:
/dir1/dir2/dir3/2013/04/04/file.pdf
and I need to convert it to:
dir4/dir5/2013/04/4/file.pdf
It's important that the leading 0 in 6th place is removed, values in this place go from 1 to 31. Can anyone help with this?
Using sed :
sed -E 's#(/[^/]*){3}(/[0-9]+/[0-9]+/)0?([0-9]+.*)#dir4/dir5\2\3#' your_file
We match the three dirs in a first group that will be disregarded (we'd be using a non-capturing group if sed supported it), then the year and month in a second group, then optionnaly the leading 0 of the day, then the rest of the day and the filename in a third group. The replacement pattern just specifies the new path root then refers to the second and third groups. I'm using # as a delimiter to avoid having to espace all the / in the pattern and replacement pattern, any character that isn't found in them would work as well.
Try it online !

Want to replace a string only at first occurrence using sed

I want to replace a special character (=) only at first occurrence.
Example:
abc=abc.def=
Expected output is:
abc.def=
I tried the following command: sed -e 's/\([^=]*\)\(=.*\)/\2/'
but the output I am getting is:
=abc.def=
Note that your example suggests you want to remove everything up to and including the first equals.
Move the equals sign into the first part of the regex, delete the remaining part of the regex (because you only need to match the part you want to remove) and replace the match with "nothing" to remove it:
sed -e 's/^[^=]*=//'

Resources