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.
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
I want to do something like this:
sed "/^[^+]/ s/\(.*$1|$2.*$\)/+\ \1/" -i file
where 2 specific String Parameters are being checked in a file and in those lines where BOTH parameters ($1 | $2) occur, a + is added at the beginning of the line if there was no + before.
Tried different variations so far and ending up either checking both but then sed'ing every line that contains 1 of the 2 Strings or some errors.
Thankful for any clarifications regarding slash and backslash escaping (respectively single/double quotes) i guess thats where my problem lies.
Edit: Wished outcome: (Folder containing bunch of text files one of which has the following 2 lines)
sudo bash MyScript.sh 01234567 Wanted
Before:
Some Random Text And A Number 01234567 and i'm Wanted.
Another Random Text with Diff Number 09812387 and i'm still Wanted.
Expected:
+ Some Random Text And A Number 01234567 and i'm Wanted.
Another Random Text with Diff Number 09812387 and i'm still Wanted.
For an input file that looks as follows:
$ cat infile
Some Random Text And A Number 01234567 and i'm Wanted.
Another Random Text with Diff Number 09812387 and i'm still Wanted.
and setting $1 and $2 to 01234567 and Wanted (in a script, these are just the first two positional parameters and don't have to be set):
$ set -- 01234567 Wanted
the following command would work:
$ sed '/^+/b; /'"$1"'/!b; /'"$2"'/s/^/+ /' infile
+ Some Random Text And A Number 01234567 and i'm Wanted.
Another Random Text with Diff Number 09812387 and i'm still Wanted.
This is how it works:
sed '
/^+/b # Skip if line starts with "+"
/'"$1"'/!b # Skip if line doesn't contain first parameter
/'"$2"'/s/^/+ / # Prepend "+ " if second parameter is matched
' infile
b is the "branch" command; when used on its own (as opposed to with a label to jump to), it skips all commands.
The first two commands skip lines that start with + or that don' t contain the first parameter; if we're on the line with the s command, we already know that the current line doesn't start with + and contains the first parameter. If it contains the second parameter, we prepend + .
For quoting, I have single quoted the whole command except for where the parameters are included:
'single quoted'"$parameter"'single quoted'
so I don't have to escape anything unusual. This assumes that the variable in the double quoted part doesn't contain any metacharacters that might confuse sed.
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.
I came upon an example of sed simulating cat -s, which will replace two or more empty lines by one empty line.
The command is below
echo -e "\n-------------\nline1\n\nline2\nline3\n\n\nline4\n\n\n\nlast line\n-------------" | sed '1s/^$//p;/./,/^$/!d'
I understand the sed part has two parts. The first one, '1s/^$//p' will take place on first line and will just print nothing to the first line of it's empty. Ok, that part I get it.
Now, for the second part, '/./,/^$/!d', it will delete the line if it does not match /./, any single character or /^$/ empty line. That covers pretty much anything, no? How come an empty line after another empty line is matched by that?
The sed manual says this:
Appending the '!' character to the end of an address specification
(before the command letter) negates the sense of the match.
The sed command /./,/^$/!d is therefore "delete rows that are not in a range defined by a line with any character until and including one blank line". So it will delete rows that are not in this kind of range.
1 -------------
2 line1
3
4 line2
5 line3
6
7
8 line4
9
10
11
12 last line
13 -------------
14
The first range is lines 1-3.
The second range is lines 4-6.
The next range is lines 8-9.
The last range is lines 12-14.
Lines 7 and 10-11 do not fall into any of the matched ranges, so they are affected by the ! modifier, and they get deleted.
I can think of ways to do this in other programming languages that would be more clear, but if all you've got is sed then this is an effective way to reduce redundant blank lines.