I use ${var//string1/string2} for replace characters or strings, now I need do the same but in a specific column awk.
try this for replace space per '_' but does not work
cat file | awk -F',' '{print ${3// /_}'
Use gsub
awk -F, -v OFS=, '{gsub(" ", "_", $3); print}' file.txt
Related
I have this file
file.txt
unknown#mail.com||unknown#mail.com||
unknown#mail2.com||unknown#mail2.com||
unknown#mail3.com||unknown#mail3.com||
unknown#mail4.com||unknown#mail4.com||
unknownpass
unknownpass2
unknownpass3
unknownpass4
How can I use the sed command to obtain this:
unknown#mail.com|unknownpass|unknown#mail.com|unknownpass|
unknown#mail2.com|unknownpass2|unknown#mail2.com|unknownpass2|
unknown#mail3.com|unknownpass3|unknown#mail3.com|unknownpass3|
unknown#mail4.com|unknownpass4|unknown#mail4.com|unknownpass4|
This might work for you (GNU sed):
sed ':a;N;/\n[^|\n]*$/!ba;s/||\([^|]*\)||\(\n.*\)*\n\(.*\)$/|\3|\1|\3|\2/;P;D' file
Slurp the first part of the file into pattern space and one of the replacements, substitute, print and delete the first line and then repeat.
Well, this does use sed anyway:
{ sed -n 5,\$p file.txt; sed 4q file.txt; } | awk 'NR<5{a[NR]=$0; next}
{$2=a[NR-4]; $4=a[NR-4]} 1' FS=\| OFS=\|
awk to the rescue!
awk 'BEGIN {FS=OFS="|"}
NR==FNR {if(NF==1) a[++c]=$1; next}
NF>4 {$2=a[FNR]; $4=$2; print}' file{,}
a two pass algorithm, caches the entries in the first round and inserts them into the empty fields, assumes the number of items match.
Here is another approach with one pass, powered by tac wrapped awk
tac file |
awk 'BEGIN {FS=OFS="|"}
NF==1 {a[++c]=$1}
NF>4 {$2=a[c--]; $4=$2; print}' |
tac
I would combine the related lines with paste and reshuffle the elements with awk (I assume the related lines are exactly half a file away):
n=$(wc -l < file.txt)
paste -d'|' <(head -n $((n/2)) file.txt) <(tail -n $((n/2)) file.txt) |
awk '{ print $1, $6, $3, $6, "" }' FS='|' OFS='|'
Output:
unknown#mail.com|unknownpass|unknown#mail.com|unknownpass|
unknown#mail2.com|unknownpass2|unknown#mail2.com|unknownpass2|
unknown#mail3.com|unknownpass3|unknown#mail3.com|unknownpass3|
unknown#mail4.com|unknownpass4|unknown#mail4.com|unknownpass4|
I have a data file separated by comma, data enclosed by "":
$ head file.txt
"HD","Sep 13 2016 1:05AM","0001"
"DT","273093045","192534"
"DT","273097637","192534" ..
I want to get the 3rd column value (0001) to be assigned to my variable.
I tried
FILE_VER=`cat file.txt | awk -F',' '{if ($1 == "HD") print $3}'`
I don't get any value assigned to FILE_VER. Please help me with correct syntax.
Another awk version:
awk -F'"' '$2 == "HD"{print $6}' file
You were almost there. Simply removing the quotes should be good enough:
foo=$(awk -F, '$1=="\"HD\""{gsub(/"/,"",$3);print $3}' file)
not sure this is the most optimal way but works:
FILE_VER=$(awk -F',' '$1 == "\"HD\"" {gsub("\"","",$3); print $3}' file.txt)
test for HD between quotes
remove quotes before printing result
You can change the file to substitute the comma and quotes to tab:
tr -s '\"," "\t' < filename | awk '{print $3}'
Maybe there is a solution using only awk, but this works just fine!
i have a 2 fields in my DB
ID25333,1429291340lNormPUC-AP_MEX_UFM-GOL_44PUC-AP_VEX_UFM-ROL_55PUCAP_MEX_UFM-DOJ_49
ID55555,1429291340lNormPUC-AP_PPP_UFM-HOL_44PUC-AF_GEX_UJM-SOL_45PUCAP_MEX_UFM-DOJ_59
and i need separate like this
ID25333,PUC-AP_MEX_UFM-GOL_44
ID25333,PUC-AP_VEX_UFM-ROL_55
ID25333,PUCAP_MEX_UFM-DOJ_49
ID55555,PUC-AP_PPP_UFM-HOL_44
ID55555,PUC-AF_GEX_UJM-SOL_45
ID55555,PUCAP_MEX_UFM-DOJ_59
with the same numbre ID
i using the AWK or grep
awk 'BEGIN{FS="PUC"}{for(i=1;i<=NF;i++)print $(i)}'
any suggestions
thanks!
With GNU awk:
$ awk -F, '{gsub(/PUC/, ","); for (i=3;i<=NF;i++)print $1",PUC"$i}' file.db
ID25333,PUC-AP_MEX_UFM-GOL_44
ID25333,PUC-AP_VEX_UFM-ROL_55
ID25333,PUCAP_MEX_UFM-DOJ_49
ID55555,PUC-AP_PPP_UFM-HOL_44
ID55555,PUC-AF_GEX_UJM-SOL_45
ID55555,PUCAP_MEX_UFM-DOJ_59
Or:
$ awk -F'(,|PUC)' '{for (i=3;i<=NF;i++)print $1",PUC"$i}' file.db
ID25333,PUC-AP_MEX_UFM-GOL_44
ID25333,PUC-AP_VEX_UFM-ROL_55
ID25333,PUCAP_MEX_UFM-DOJ_49
ID55555,PUC-AP_PPP_UFM-HOL_44
ID55555,PUC-AF_GEX_UJM-SOL_45
ID55555,PUCAP_MEX_UFM-DOJ_59
If you like awk
awk -F, ' -v OFS=','
{
id=$1
split($2,line,"PUC")
for(i=2;i<=length(line);i++)
print id,"PUC" line[i]
}'
With GNU awk for fixed width fields:
$ awk -v FIELDWIDTHS="8 15 21 21 21" '{for (i=3;i<=NF;i++) print $1 $i}' file
ID25333,PUC-AP_MEX_UFM-GOL_44
ID25333,PUC-AP_VEX_UFM-ROL_55
ID25333,PUCAP_MEX_UFM-DOJ_49
ID55555,PUC-AP_PPP_UFM-HOL_44
ID55555,PUC-AF_GEX_UJM-SOL_45
ID55555,PUCAP_MEX_UFM-DOJ_59
I have this value
option 'staticip' '5.5.5.1'
I want to print only 5.5.5.1 without quote sign. I have use
cat /etc/filename | grep staticip | awk '{print $3}'
but the result come with '5.5.5.1'
Or, you can use tr to remove the offending characters:
cat /etc/filename | grep staticip | awk '{print $3}' | tr -d \'
You can use awk's gsub() function to change the quotes to nothing.
awk '{gsub(/'"'"'/, "", $3); print $3}'
Note this is really gsub(/'/, "", $3). The ugliness comes from the need to glue quotes together.
awk '$2=="staticip" && $0=$4' FS="'"
Result
5.5.5.1
To remove the ' from the awk output you can use
sed "s/^'//;s/'$//"
This command removes the ' only at the beginning and the end of the output line and is not so heavy as to use awk and not so general if using tr.
awk is much bgiger in memory and tr removes all ' from the output what is not always intended.
You could use awks substr function or pipe that to the cut command. I leave you to read the man page for awk substr.
I have one file which contains three fields separated by two spaces. I need to get only third field from file. File content is as in following example:
kuldeep Mirat Shakti
balaji salunke pune
.
.
.
How can I get the third field?
To get the 3rd field, assuming you don't have any "embedded spaces", just
awk '{print $3}' file
awk by default sets whitespaces as field delimiters. So even if you have 2 spaces or more, the 3rd field is always $3.
However, if you want to be specific, then specify a Field delimiter
awk -F" " '{print $3}' file
If you have other choices, a Ruby one
ruby -F" " -ane 'print $F[2]' file
ruby -ane 'print $F[2]' file
Update: If you need to get all fields after 3rd,
awk -F" " '{$1=$2=$3=""}1' OFS=" " file # add a pipe to `sed 's/^[ \t]*//'` if desired
ruby -F" " -ane 'puts $F[3..-1].join(" ")' file
Use awk:
awk -F' ' '{print $3}' file
This also works if fields may contain embedded spaces.
To get the third field of each line, pipe through awk, e.g
cat filename | awk '{print $3}'
If you just want to get the third field of the first line, use head, too:
cat filename | head -n 1 | awk '{print $3}'
Given #balaji's comment to #kurani's answer:
perl -pe 's/^.*? .*? //' filename
awk -F' ' '{for(i=3; i<NF; i++) {printf("%s%s",$i,FS)}; print $NF}' filename
less filename | cut -d" " -f 3