find pattern in a column and replace it with awk - awk

I was trying to do the following.
I was trying to put column 1 when I found a pattern that would be "undefined", for example:
I have my file.txt file that contains
192.168.1.1, Paul
192.168.2.2, undefined
Here it is "undefined", then replace it with the first column in the row where it is "undefined". (192.168.2.2)
192.168.1.1, Paul
192.168.2.2, 192.168.2.2
Can somebody help me?

using awk
$ awk -F", " '$2~/undefined/{ print $1 FS $1; next}1' file
192.168.1.1, Paul
192.168.2.2, 192.168.2.2

You can use sed:
sed 's/\(.*\), undefined$/\1, \1/' file.txt
or
sed -r 's/(.*), undefined$/\1, \1/' file.txt

This line works for your example, no matter the separator is , or ,(space)
awk -F, '1+sub(/undefined$/,$1)' file

Related

How to print specific string from a sentence using awk

I have the following sentence within a file
FQDN=joe.blogs.com.
How can I print the string "joe"
I have tried using -->> awk -F"=" '{print $2}' file
but this returns joe.blogs.com as "=" is the delimiter.
Is it possible to use 2 delimiters on the same line?
You might use regular expression as FS. Let file.txt content be
FQDN=joe.blogs.com.
then
awk 'BEGIN{FS="[=.]"}{print $2}' file.txt
output
joe
In case you are ok with sed, could you please try following.
sed 's/.*=\([^.]*\)\..*/\1/' Input_file
With GNU grep and using its -oP flag we could try following too.
grep -oP '(.*=)\K([^.]*)' Input_file
You could use GNU grep:
grep -oP '(?<=FQDN=)[^.]+' file
^ all characters up to a '.'
^ lookbehind for 'FQDN='
^ only print match and Perl style regex
Or with Perl:
perl -lne 'print $1 if /(?<=FQDN=)([^.]+)/' file
With awk I would probably do:
awk 'BEGIN{FS="[.=]"} /FQDN=/{print $2}' file
why not keeping it simple and pipe awk?
awk -F"=" '{print $2}' | awk -F"." '{print $1}'
can I use two field delimiters on one line?
No. You may do further string manipulation as post processing, or you could use a regex as field delimiter.
Another option is to use awk's split function:
awk -F= '{ split($2,map,".");print map[1] }' file
Split the second = separated field into the array map using "." as the delimiter. Print the first index of the array.

awk command to read a key value pair from a file

I have a file input.txt which stores information in KEY:VALUE form. I'm trying to read GOOGLE_URL from this input.txt which prints only http because the seperator is :. What is the problem with my grep command and how should I print the entire URL.
SCRIPT
$> cat script.sh
#!/bin/bash
URL=`grep -e '\bGOOGLE_URL\b' input.txt | awk -F: '{print $2}'`
printf " $URL \n"
INPUT_FILE
$> cat input.txt
GOOGLE_URL:https://www.google.com/
OUTPUT
https
DESIRED_OUTPUT
https://www.google.com/
Since there are multiple : in your input, getting $2 will not work in awk because it will just give you 2nd field. You actually need an equivalent of cut -d: -f2- but you also need to check key name that comes before first :.
This awk should work for you:
awk -F: '$1 == "GOOGLE_URL" {sub(/^[^:]+:/, ""); print}' input.txt
https://www.google.com/
Or this non-regex awk approach that allows you to pass key name from command line:
awk -F: -v k='GOOGLE_URL' '$1==k{print substr($0, length(k FS)+1)}' input.txt
Or using gnu-grep:
grep -oP '^GOOGLE_URL:\K.+' input.txt
https://www.google.com/
Could you please try following, written and tested with shown samples in GNU awk. This will look for string GOOGLE_URL and will catch further either http or https value from url, in case you need only https then change http[s]? to https in following solution please.
awk '/^GOOGLE_URL:/{match($0,/http[s]?:\/\/.*/);print substr($0,RSTART,RLENGTH)}' Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
/^GOOGLE_URL:/{ ##Checking condition if line starts from GOOGLE_URL: then do following.
match($0,/http[s]?:\/\/.*/) ##Using match function to match http[s](s optional) : till last of line here.
print substr($0,RSTART,RLENGTH) ##Printing sub string of matched value from above function.
}
' Input_file ##Mentioning Input_file name here.
2nd solution: In case you need anything coming after first : then try following.
awk '/^GOOGLE_URL:/{match($0,/:.*/);print substr($0,RSTART+1,RLENGTH-1)}' Input_file
Take your pick:
$ sed -n 's/^GOOGLE_URL://p' file
https://www.google.com/
$ awk 'sub(/^GOOGLE_URL:/,"")' file
https://www.google.com/
The above will work using any sed or awk in any shell on every UNIX box.
I would use GNU AWK following way for that task:
Let file.txt content be:
EXAMPLE_URL:http://www.example.com/
GOOGLE_URL:https://www.google.com/
KEY:GOOGLE_URL:
Then:
awk 'BEGIN{FS="^GOOGLE_URL:"}{if(NF==2){print $2}}' file.txt
will output:
https://www.google.com/
Explanation: GNU AWK FS might be pattern, so I set it to GOOGLE_URL: anchored (^) to begin of line, so GOOGLE_URL: in middle/end will not be seperator (consider 3rd line of input). With this FS there might be either 1 or 2 fields in each line - latter is case only if line starts with GOOGLE_URL: so I check number of fields (NF) and if this is second case I print 2nd field ($2) as first record in this case is empty.
(tested in gawk 4.2.1)
Yet another awk alternative:
gawk -F'(^[^:]*:)' '/^GOOGLE_URL:/{ print $2 }' infile

How to edit special character in Linux files using with SED?

File name: File.txt
Content:
Vignesh Mani Bani Ravi
Result should come with,
"Vignesh", "Mani", "Bani", "Ravi"
Can anyone help me how can I get the expected result?
I have tried this command.
sed -e 's/^ /" ",/g' File.txt
It's not working. Please advise me.
$ sed 's/ /", "/g; s/^\|$/"/g' file
"Vignesh", "Mani", "Bani", "Ravi"
1st solution: If your actual Input_file is same as shown sample then following may help you here.
awk -v s1='"' -v s2=',' '{gsub(/ /,s1 s2 OFS s1);gsub(/^|$/,s1)} 1' Input_file
2nd solution:
awk -v s1='"' 'BEGIN{OFS=s1", "s1} {gsub(/^|$/,s1);$1=$1} 1' Input_file
I would do it with awk:
awk -v OFS=", " -v q='"' '{for(i=1;i<=NF;i++)$i=q $i q}7' file
This might work for you (GNU sed):
sed 's/\S\+/"&"/g;s/\s\+/, /g' file
Surround non-white space by double quotes. Replace each set of white space by a comma followed by a space.

awk sed grep to extract patten with special characters

I am trying to understant the switchs and args in awk and sed
For instance, to get the number next to nonce in the line form the file response.xml:
WWW-Authenticate: ServiceAuth realm="WinREST", nonce="1828HvF7EfPnRtzSs/h10Q=="
I use by suggestion of another member
nonce=$(sed -nE 's/.*nonce="([^"]+)"/\1/p' response.xml)
to get the numbers next to the word idOperation in the line below I was trying :
idOper=$(sed -nE 's/.*idOperation="([^"]+)"/\1/p' zarph_response.xml)
line to extract the number:
{"reqStatus":{"code":0,"message":"Success","success":true},"idOperation":"185-16-6"}
how do I get the 185-16-6 ?
and if the data to extract has no ""
like the 1 next to operStatus ?
{"reqStatus":{"code":0,"message":"Success","success":true},"operStatus":1,"amountReceived":0,"amountDismissed":0,"currency":"EUR"}
Following awk may help you on same.
awk -F"\"" '/idOperation/{print $(NF-1)}' Input_file
Solution 2nd: In sed following may help you on same.
sed '/idOperation/s/\(.*:\)"\([^"]*\)\(.*\)/\2/' Input_file
EDIT: In case you want to get the digit after string operStatus then following may help you on same.
awk 'match($0,/operStatus[^,]*/){;print substr($0,RSTART+12,RLENGTH-12)}' Input_file
Using grep perl-style regexes
grep -oP "nonce=\"\K(.*)?(?=\")" Input_file
grep -oP "idOperation\":\"\K(.*)?(?=\")" Input_file
If the input is json you can use jq
jq .idOperation Input_file

How to replace value from one column with value from another column in the same file

I have a file with thousands of lines and columns, two of the columns are IP1 and IP2. IP1 is always the same 192.168.100.1
*example.com,192.168.100.1,10.10.1.1,,5effd70e9d99b1acf,10,63,58,42,0,21,84055280,0
example2.com,192.168.100.1,10.10.1.50,,255b2l429c8f23ee,10,63,37,42,1,21,1451066297,0
example3.com,192.168.100.1,10.10.1.58,,589b7a5f8677b,11,68,37,42,1,20,1451066297,0
.............*
I want to replace the value of IP1 with value of IP2, and delete the value of IP2.
I tried this:
sed -i 's/192\.168\.100\.1/$(grep 192\.168\.100\.1 file | awk -F',' '{print $2}')/' file
The following error occured:
sed: -e expression #1, char 68: unterminated `s' command
Please help.
awk to the rescue! eliminate sed, this should do...
awk -F, -v OFS=, '{$2=$3;$3=""}1' file
sed to the rescue! eliminate awk, this should do...
sed -i 's/192\.168\.100\.1,//' file
This sed command finds the string "192.168.100.1," and replace it by nothing.
. has a special meaning in a sed command, so it requires backslash. More info on the man pages.