Replace two characters with sed dynamically - unix

I have the following strings
C:/data
D:/backups
C:/Users/Guest/old_data
F:/files/new
How can I replace the first two characters with /cygdrive/LOWERCASE_DRIVE_LETTER?
RESULT
/cygdrive/c/data
/cygdrive/d/backups
/cygdrive/c/Users/Guest/old_data
/cygdrive/f/files/new

awk -F':' 'sub(/../,"/cygdrive/"tolower($1))' file
Brief explanation,
-F':': set ':' as the field separator.
tolower($1): return thee lower case of $1
sub(/../,"/cygdrive/"tolower($1)): substitute the first 2 character to "/cygdrive/"tolower($1)

This might work for you (GNU sed):
sed 's/\(.\):/\/cygdrive\/\l\1/' file
Remember by grouping the first character followed by a :. Then insert /cygdrive/ and lowercase the group i.e. the first character.

Could you please try following.
awk 'BEGIN{FS=OFS="/"}{sub(/:/,"",$1);$1=tolower($1);print "/cygdrive/" $0}' Input_file

Related

Unix: multi and single character delimiter in cut or awk commands

This is the string I have:
my_file1.txt-myfile2.txt_my_file3.txt
I want to remove all the characters after the first "_" that follows the first ".txt".
From the above example, I want the output to be my_file1.txt-myfile2.txt. I have to search for first occurrence of ".txt" and continue parsing until I find the underscore character, and remove everything from there on.
Is it possible to do it in sed/awk/cut etc commands?
You can't do this job with cut but you can with sed and awk:
$ sed 's/\.txt/\n/g; s/\([^\n]*\n[^_]*\)_.*/\1/; s/\n/.txt/g' file
my_file1.txt-myfile2.txt
$ awk 'match($0,/\.txt[^_]*_/){print substr($0,1,RSTART+RLENGTH-2)}' file
my_file1.txt-myfile2.txt
Could you please try following, written based on your shown samples.
awk '{sub(/\.txt_.*/,".txt")} 1' Input_file
Simply substituting everything from .txt_ to till last of line with .txt and printing the line here

Trim Leading and trailing Spaces in Awk

I have a file which contains 1 line like below
VINOTH |KARTHICK |RAVI
I'm using the below command to remove the leading and trailing spaces , but it's not not working.
awk '{ gsub(/^[ \t]+|[ \t]+$/, ""); print }' Input_File
Please help.
Required Output.
VINOTH|KARTHICK|RAVI
You may use
sed 's/[ \t]*|[ \t]*/|/g;s/^[ \t]*\|[ \t]*$//g' Input_File
There are two regexps here:
s/[ \t]*|[ \t]*/|/g replaces all | enclosed with optional whitespaces with a single | (the | in the regex matches a literal | char as per BRE POSIX standard)
s/^[ \t]*\|[ \t]*$//g removes all whitespaces at the start and end of lines. Note that \| here is an OR operator (escaped because the BRE POSIX syntax is used).
See the online demo.
Could you please try following(since your sample input and expected output are not clear so didn't test it).
awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")} 1' Input_file

sed: remove digits after word

I have a simple sed question.
I have data like this:
2600,Sale,"Approved 911973",244.72
2601,Sale,"Approved 04735C",490.51
2602,Sale,"Approved 581068",52.82
2603,Sale,"Approved 009275",88.10
How do I make it like this:
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
Notice the numbers after approved are gone as well as the quotes. I can remove quotes with:
sed 's/,$//gn' file
but I don't know how to remove the spaces and digits.
Thanks!
sed "s/\"Approved[^,]*/Approved/g"
It finds the quoted "Approved" followed by any non-comma character, up until the first comma encountered, and replaces it with Approved (no quotes)
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
Using extended regex with sed:
sed -r 's/"([^[:space:]]*)[^"]*"/\1/g' file
The above regex targets for any quoted string. If you want to target the string Approved, then:
sed -r 's/"(Approved)[^"]*"/\1/g' file
With basic regex:
sed 's/"\(Approved\)[^"]*"/\1/g' file
To target any quoted string, change Approved to [^[:space:]]*
One way using awk(only if the other columns does not contain multiple words as in your sample):
awk -F"[ ,]" '{gsub("\"","");$1=$1}1' OFS=, file
awk -F'[," ]' '{OFS=","; print $1,$2,$4,$7}' file
Output:
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
I suppose there is no other whitespace.

Sed replace only exact match

I wan't to replace a string like Europe12 with Europe12_yesturday in a file. Without changing the Europe12-36 strings that also exists in the file.
I tried:
$basename=Europe12
sed -i 's/\b$basename\b/${basename}_yesterday/g' file.txt
but this also changed the Europe12-36 strings.
Require a space or end of line character:
sed 's/Europe12\([ ]|$\)/Europe12_yesturday\1/g' input
Manually construct the delimiter list you want instead of using \b, \W or \<. - is not part of the word characters (alphanumericals), so that's why this also matches your other string. So try something like this, expanding the list as needed: [-a-zA-Z0-9].
You can do it in 2 times:
sed -e 's/Europe12/Europe12_yesturday/g' -e 's/Europe12_yesturday-36/Europe12-36/g' file.txt
sed 's/\(Europe12[[:blank:]]\)/\1_yesturday/g;s/Europe12$/&_yesturday/' YourFile
[[:blank:]] could be completeted with any boundary you accept also like .,;:/]) etc (be carrefull of regex meaning of this char in this case)
It is little late to reply..
It can be achieved easily by "word boundary" notation (\<..\>)
sed -i 's/\<$basename\>/${basename}_yesterday/g' file.txt

Replacing the last column in a unix file with another value

I would like to replace the last column values with another value using vim editor or sed command.I tried the below command but it replaces the data which is already present in my 2nd column sometimes.
:%s/,3/,2/
My sample data:
410339,166,1430,3
410340,112,1840,3
410341,109,1315,3
410342,123,1435,3
410343,230,3200,3
410344,857,36975,3
410345,125,4440,3
410346,105,1460,3
410348,122,1150,3
410349,314,2380,3
410350,132,4650,3
410351,136,7465,3
410352,103,1775,3
410353,101,1095,3
410354,101,1360,3
You'll need to indicate that you want the end-of-line:
:%s/,3$/2/
To complete your attempt in Vim, just anchor the matched expression to the end of the line with $.
:%s/,3$/,2/
Produces:
410339,166,1430,2
410340,112,1840,2
410341,109,1315,2
410342,123,1435,2
410343,230,3200,2
410344,857,36975,2
410345,125,4440,2
410346,105,1460,2
410348,122,1150,2
410349,314,2380,2
410350,132,4650,2
410351,136,7465,2
410352,103,1775,2
410353,101,1095,2
410354,101,1360,2
I would use awk:
awk '{$NF=2}1' FS=, OFS=,
This unconditionally makes the last column have the value 2. If the desired replacement is a string, you will need to use quotes or the more flexible:
awk '{$NF=r}1' FS=, OFS=, r="the string to put in the last column"
You can restrict the replacement to those columns that have the value 3 with:
awk '$NF==3{$NF=r}1' FS=, OFS=, r="the string to put in the last column"
And, to do this in vim, just do:
:%! awk ...
With GNU sed:
If the last column is only ever '3':
sed -i 's/3$/2/' file
If the last column could be something like '13':
sed -i 's/,3$/,2/' file
The -i flag:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)

Resources