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.
Related
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.
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 !
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.
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).