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.
Say I have a string:
ap=test:::bc=exam:::dc=comic:::mp=calc:::
Read in a linux box, i need to remove say bc=exam, the key is always the same, but the value can be any value, string or digits, and the placement of the key value pair can be anywhere in the string.
i've got to
sed -e 's/:::bc=\(.*:::\)*/\1/'
which only removes the key and a delimiter.
or
sed -e 's/:::bc=.*\(:::\)*/\1/'
which is removing everything from the key on.
Thanks in advance.
Since your values do not contain semicolons, you may match them with a negated bracket expression, [^:]*:
sed 's/:::bc=[^:]*//' file
See the online sed demo.
The :::bc=[^:]* matches :::bc and then any 0+ chars other than a colon.
I'm having a .txt file looking like this (along about 400 rows):
lettuceFMnode_1240 J_C7R5_99354_KNKSR3_Oligomycin 81.52
lettuceFMnode_3755 H_C1R3_99940_KNKSF2_Tubulysin 70
lettuceFMnode_17813 G_C4R5_80184_KNKS113774F_Tetronasin 79.57
lettuceFMnode_69469 J_C11R7_99276_KNKSF2_Nystatin 87.27
I want to edit the names in the entire 2nd column so that only the last part will stay (meaning delete anything before that, so in fact leaving what comes after the last _).
I looked into different solutions using a combination of cut and sed, but couldn't understand how the code should be built.
Would appreciate any tips and help!
Thank you!
Here's one way:
perl -pe 's/^\S+\s+\K\S+_//'
For every line of input (-p) we execute some code (-e ...).
The code performs a subtitution (s/PATTERN/REPLACEMENT/).
The pattern matches as follows:
^ beginning of string
\S+ 1 or more non-whitespace characters (the first column)
\s+ 1 or more whitespace characters (the space after the first column)
\K do not treat the text matched so far as part of the final match
\S+ 1 or more non-whitespace characters (the second column)
_ an underscore
Because + is greedy (it matches as many characters as possible), \S+_ will match everything up to the last _ in the second column.
Because we used \K, only the rest of the pattern (i.e. the part of the match that lies in the second column) gets replaced.
The replacement string is empty, so the match is effectively removed.
With sed:
sed 's/ [^ ]*_/ /' file
Replace first space followed by non-space characters ([^ ]*) followed by _ widh one space.
I have an output like this:
a/foo bar /
b/c/foo sth /xyz
cc/bar ghj /axz/byz
What i want is just this line:
a/foo bar /
To be more clear, I want those line ending with a specific string. I want to grep lines that have a / character at their last column.
You can use $ like this:
$ grep '/$' file
a/foo bar /
As $ stands for end of line, /$ matches those lines whose last character is a /.
grep '/$'
slash is not special character for grep and $ means match expression at the end of a line.
You can even grep the last column with only backlash at last column (but not the only column in the line)
I assumed tha the last column of a line is a string with more than one white space in front the string and no more character after the string. This assumption does not fulfill the requirement if there has only one column in that line because it does not need space in front of it to show it is last column if there has only one column.
By enable perl regular expressions (-P),
grep -P '\s+/$'
\s means matches any whitespace character (space, tab, newline)
plus sign means match 1 or more times for preceding element
$ means end of string
OR refer to Character Classes and Bracket Expressions
grep '[[:space:]]\+/$'
OR
grep '[[:blank:]]\+/$'
‘[:blank:]’ Blank characters: space and tab.
‘[:space:]’ Space characters: in the ‘C’ locale, this is tab, newline,
vertical tab, form feed, carriage return, and space. It is a synonym for '\s'.
Refer to #fedorqui, the backslash after ]] is used to distinguish with
the literal +. Thanks for the explanations.
Sorry if wrong for perl answer because I never use or learn Perl expression but really hope can help you find the last column slash so may be you can read these for more information for searching backspace with slash at end of line
grep with regexp: whitespace doesn't match unless I add an assertion
Regular expressions in Perl
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).