echo specific string inside quotes from variable - bash

I need a script that echo one of strings wrapped in quotes.
For example, from variable x="C. Ronaldo" "dos Santos Aveiro" "Cristiano Ronaldo" i want to echo the third one.
So I want to get output like: "Cristiano Ronaldo"
I've tried it with echo $x | awk '{print $3}' but it gives me "dos..
Any help?

By default awk splits records by spaces into fields, given your string, "dos is the third field. To parse this string the way you desire GNU awk's FPAT is required. E.g:
awk -v FPAT='"[^"]*"' '{print $3}'

Related

How can I parse CSV files with quoted fields containing commas, in awk?

I have a big CSV field, and I use awk with the field separator set to a comma. However, some fields are quoted and contain a comma, and I'm facing this issue:
Original file:
Downloads $ cat testfile.csv
"aaa","bbb","ccc","dddd"
"aaa","bbb","ccc","d,dd,d"
"aaa","bbb","ccc","dd,d,d"
I am trying this way:
Downloads $ cat testfile.csv | awk -F "," '{ print $2","$3","$4 }'
"bbb","ccc","dddd"
"bbb","ccc","d
"bbb","ccc","dd
Expecting result:
"bbb","ccc","dddd"
"bbb","ccc","d,dd,d"
"bbb","ccc","dd,d,d"
I would use a tool that is able to properly parse CSV, such as xsv. With it, the command would look like
$ xsv select 2-4 testfile.csv
bbb,ccc,dddd
bbb,ccc,"d,dd,d"
bbb,ccc,"dd,d,d"
or, if you really want every value quoted, with a second step:
$ xsv select 2-4 testfile.csv | xsv fmt --quote-always
"bbb","ccc","dddd"
"bbb","ccc","d,dd,d"
"bbb","ccc","dd,d,d"
Include (escaped) quotes in your field separator flag, and add them to your output print fields:
testfile.csv | awk -F "\",\"" '{print "\""$2"\",\""$3"\",\""$4}'
output:
"bbb","ccc","dddd"
"bbb","ccc","d,dd,d"
"bbb","ccc","dd,d,d"
If gawk or GNU awk is available, you can make use of FPAT, which matches the fields, instead of splitting on field separators.
awk -v FPAT='([^,]+)|(\"[^\"]+\")' -v OFS=, '{print $2, $3, $4}' testfile.csv
Result:
"bbb","ccc","dddd"
"bbb","ccc","d,dd,d"
"bbb","ccc","dd,d,d"
The string ([^,]+)|(\"[^\"]+\") is a regex pattern which matches either of:
([^,]+) ... matches a sequence of any characters other than a comma.
(\"[^\"]+\") ... matches a string enclosed by double quotes (which may include commas in between).
The parentheses around the patterns are put for visual clarity purpose and the regex will work without them such as FPAT='[^,]+|\"[^\"]+\"' because the alternative | has lower precedence.

Feed literal string bash variable to awk and gsub

I want to edit a column in a text file by feeding a bash variable containing a literal string to awk and gsub
I have tried various version of the command below. It works for a variable that does not contain any special characters but not for one that needs to be interpreted as a literal string.
#create intial file
echo -e "SOD1:c.112G>A(p.[G38R])"'\t'"SOD1:c.112G>A(p.[G38R]);NA" > testfile
#set variable
var="SOD1:c.112G>A(p.[G38R])"
#test awk
more testfile | awk -F '\t' -v OFS='\t' -v var="${var}" '{gsub(var,"",$2)}1'
I want to delete the variable only in the second column not in the first.
Thanks in advance for your help
You can just put your var definition and your awk command in one line like this:
var='SOD1:c.112G>A\(p.\[G38R\]\)'; awk -F '\t' -v OFS='\t' -v var="$var" '{gsub(var,"",$2)}1' testfile

How can I change the awk delimiter for a part of my script?

I have an input string that is formatted like this:
string1;string2"string3";string4
I want to parse this file to get the value of string3 using awk. To do this, I can first delimit by ;, print the second segment, and then delimit by " and print the second segment. Example using pipes:
$ echo 'string1;string2"string3";string4' | awk -F\; '{print $2}' | awk -F\" '{print $2}';
string3
I want to combine this into a single awk command, but I do not know how to change the field separator during my command. Is there syntax I can use in awk to change my separator?
You can use split function inside awk:
s='string1;string2"string3";string4'
awk -F ';' 'split($2, a, /"/){print a[2]}' <<< "$s"
string3
As per the linked doc:
split(string, array [, fieldsep [, seps ] ])
Divide string into pieces separated by fieldsep and store the pieces in array and the separator strings in the seps array.
Could you please try following and let me know how it goes then.
echo 'string1;string2"string3";string4' | awk -F'[;"]' '{print $3}'
So above is creating multiple delimiters by mentioning -F option in awk and then I am setting delimiters as chars(; ") so then string3 will be 3rd field and you could merge your awk like that. I hope this helps you.
EDIT: Apologies MODs/all, I am new to this site, so I am adding another alternative for this question's answer.
Thank you Questionmark, it encourages me. So in case you have only have two occurrences of " in your string and you want to get rid of this delimiter then following could help you:
echo 'string1;string2"string3";string4' | awk '{match($0,/\".*\"/);print substr($0,RSTART+1,RLENGTH-2)}'
In the above code I am matching the regex using the match functionality of awk, so once it matches the specific string then I am printing the specific match(where RSTART and RLENGTH are the built-in variables in awk which will be set only when inside, the regex match is TRUE, so they are printed. I hope this will help too.

How to send parameters on AWK to replace a parameter. Unix Korn Shell

I'm trying to replace a parameter to change a value when the AWK is used to search for a string in a file.
is this possible? I'm doing this.
DisplayMessage()
{
##Parameter 1 = Message ID.
MessageFile="/dev/fs/C/Users/salasfri/Desktop/Messages.txt"
Message=$(awk '$1 ~ /^'$MessageID'$/ {$1=""; print $0}' $MessageFile)
}
the Message File looks for this in the file "MessageFile":
0005 The file ${1} was not tranmitted.
it search for 0005 and get the message "The file ${1} was not tranmitted."
I want to replace ${1} with the name of the file
this could be possible with awk? any idea?
this should do...
awk '$1~/^'$MessageID'$/ {$1=""; sub("\\${1}",FILENAME); print}'
but perhaps you want to change to
awk -v mid="${MessageID}" '$1==mid {$1=""; sub("\\${1}",FILENAME); print}'
since you're looking for an exact match, not pattern match. Also better to use awk variables instead of quote dance.

Replace a field with a value in the input data

I have a data
A BC 3 CD
note that the spaces in between the fields are not constant
Now I want to replace the third field with another number which is stored in another variable v.
I have used awk in this way:
echo "A BC 3 CD" | awk '{$3 = $v; print}'
The output is the third field is getting replaced with the entire line(wrong output)
Is there any possible to get the desired output without changing the spaces in the original data?
Thanks for your help!!
Try this:
$ v=25
$ echo "A BC 3 CD" | gawk '{print gensub(/[^ \t]+/, v, 3)}' v="$v"
A BC 25 CD
In your code, $v is being evaluated by awk, not bash, with v=0. Hence $3 gets replaced by $0, which is entire line.
Note that gensub is gawk enhancement...

Resources