I have this input
name num value
A 1010232 1
A 1010232 2
A 1010232 3
B 2565214 1
B 2565214 2
B 2565214 3
C 6111111 2
C 6111111 3
.
.
O need output like this:
the name C has no "1" value actually
I don't have any idea about the way to solve it
$ cat file
name num value
A 1010232 1
A 1010232 2
A 1010232 3
B 2565214 1
B 2565214 2
B 2565214 3
C 6111111 2
C 6111111 3
$ awk '
NR>1 { seen[$1,$3]++; names[$1]; vals[$3] }
END {
for (name in names)
for (val in vals)
if (!seen[name,val])
printf "the name %s has no \"%s\" value actually\n", name, val
}
' file
the name C has no "1" value actually
You could try:
awk -f chk.awk input.txt
where chk.awk is:
{
a[$1,$3]++
}
END {
if (!("C","1") in a)
print "the name C has no \"1\" value"
}
Related
Input data:
name date
G
A 2011-01-21
A
B
C 2011-02-04
D
D 2011-03-26
E 2011-05-13
F 2011-02-20
G 2011-05-10
G
H
A
My desired output is a list of distinct values from name and date disgarding rows containing where name is a duplicate and date is blank:
name date
A 2011-01-21
B
C 2011-02-04
D 2011-03-26
E 2011-05-13
F 2011-02-20
G 2011-05-10
H
My awk code below produces this result:
awk 'BEGIN { FS=OFS="\t"}
NR==1 { print }
NR>1 { a[$1]++ }
NR>1 && $2!="" { b[$1]=$2 }
NR>1 && $2=="" { c[$1]=$2 }
END { for (i in a) {
if ( c[i] ) {print i,b[i]}
else {print i,b[i]}
}
}
' test.tsv
However, it shouldn't produce the desired result because in the event c[i] is empty, b[i] should be empty and it should give up. What am I missing here please?
your c[i] is useless, you always print the same combination. You can simplify it a bit and I think it will get clearer
$ awk 'NR==1 {print; next}
{a[$1]=a[$1]==""?$2:a[$1]}
END {for(k in a) print k,a[k]}' file | column -t
name date
A 2011-01-21
B
C 2011-02-04
D 2011-03-26
E 2011-05-13
F 2011-02-20
G 2011-05-10
H
only update the mapping if the value is not blank, so this will capture the first non-blank value for each key if there is any.
Assuming the values are dates you can replace the middle block with !a[$1]{a[$1]=$2}
I have a cell array that has strings in each row. I want to count the number of characters in each row of the cell array, including spaces. How do I do this in matlab?
Thanks for your answer, I'm a bit stuck though in my code
fid = fopen('thenames.txt', 'w');
if fid ~= -1
disp (' The file opened sucessfully')
else
disp (' The file did not open sucessfully')
end
string1 = input('Enter a name:','s');
countstr =1;
fprintf(fid, 'Name %d is %s\n', countstr, string1)
TF = strcmp ('stop', string1);
while TF == 0;
countstr = countstr+1;
string1 = input ('Enter a name:','s');
TF = strcmp ('stop', string1);
if TF ==0
fprintf(fid, 'Name %d is %s\n', countstr, string1)
elseif TF == 1
disp ('Ok. No more names')
end
end
totalnames = countstr - 1;
fprintf(fid, 'There were %d total names given\n', totalnames)
fid = fopen('thenames.txt');
if fid ~= -1
disp (' The file opened sucessfully')
else
disp (' The file did not open sucessfully')
end
cellarray2 = [];
cellarray2 = textscan (fid ,'%s %d %s %s');
newcellarray = {cellarray2{4}}
charsPerRow = sum(cellfun(#numel,newcellarray),2)
I am ultimately trying to end up with a cell array that will store the name as a string in the first column and the second column will store the number of characters within the string as an integer. That would be the last bit of my code starting from cellarray2
Say you have a cell array C:
>> C = {'a','b2','c';'x','y','z';'aa','bb','cc'}
C =
'a' 'b2' 'c'
'x' 'y' 'z'
'aa' 'bb' 'cc'
Then use cellfun and sum:
>> charsPerRow = sum(cellfun(#numel,C),2)
charsPerRow =
4
3
6
Say you want to tag this on to the cell:
>> C2 = [C num2cell(charsPerRow)]
C2 =
'a' 'b2' 'c' [4]
'x' 'y' 'z' [3]
'aa' 'bb' 'cc' [6];
How to do something equivalent to this:
In: A = [ 1 2 3 ]
In: B = 2 * A
In: B
Out: [ 2 4 6 ]
This method gets part of the way:
In: do for [i in "1 2 3"] { print 2*i }
Out:
2
4
6
But I want to return another list/array that can be used in further operations.
As you already found out, using space-delimited words is the only way to simulate arrays. So you must format the output again as a string in which the single entries are separated by spaces:
out = ''
do for [i in "1 2 3"] {
out = out . sprintf('%d ', 2*i)
}
print sprintf('%d entries: %s', words(out), out)
This prints
3 entries: 2 4 6
If using floats, you must use e.g. '%f' to format the output:
out = ''
do for [i in "1.1 2.2 3.3"] {
out = out . sprintf('%f ', 2*i)
}
print sprintf('%d entries: %s', words(out), out)
words counts the words in a string, and you can use word to extract a certain word from the string (starting from 1):
print word(out, 2)
4
I have the following matrix array B :
B=[1 2 3; 10 20 30 ; 100 200 300 ; 500 600 800];
Which through a code is combined to form possible combinations between the values. The results are stored in cell G. Such that G :
G=
[1;20;100;500]
[0;30;0;800]
[3;0;0;600]
.
.
etc
I want to format the results based on which value from B is chosen :
[1 2 3] = 'a=1 a=2 a=3'
[10 20 30] = 'b=1 b=2 b=3'
[100 200 300]= 'c=1 c=2 c=3'
[500 600 800]= 'd=1 d=2 d=3'
Example, using the results in the current cell provided :
[1;20;100;500]
[0;30;0;800]
[3;0;0;600]
Should print as
a=1 & b=2 & c=1 & d=1
a=0 & b=3 & c=0 & d=3 % notice that 0 should be printed although not present in B
a=3 & b=0 & c=0 & d=2
Note that the cell G will vary depending on the code and is not fixed. The code used to generate the results can be viewed here : Need help debugging this code in Matlab
Please let me know if you require more info about this.
You can try this:
k = 1; % which row of G
string = sprintf('a = %d, b = %d, c = %d, d = %d',...
max([0 find(B(1,:) == G{k}(1))]), ...
max([0 find(B(2,:) == G{k}(2))]), ...
max([0 find(B(3,:) == G{k}(3))]), ...
max([0 find(B(4,:) == G{k}(4))]) ...
);
For instance, for k = 1 of your example data this results in
string =
a = 1, b = 2, c = 1, d = 1
A short explanation of this code (as requested in the comments) is as follows. For the sake of simplicity, the example is limited to the first value of G and the first line of B.
% searches whether the first element in G can be found in the first row of B
% if yes, the index is returned
idx = find(B(1,:) == G{k}(1));
% if the element was not found, the function find returns an empty element. To print
% a 0 in these cases, we perform max() as a "bogus" operation on the results of
% find() and 0. If idx is empty, it returns 0, if idx is not empty, it returns
% the results of find().
val = max([0 idx])
% this value val is now formatted to a string using sprintf
string = sprintf('a = %d', val);
I have a pretty big array and I want to delete the 2nd, 8th, 14th etc. element from an array. My array currently is like this:
Element1 x A B C
Element 2 y A B C
Element 3 z A B C
Broadly, I want to delete the x, y and z (just as an example, my array is slighly more complex). And pull up the rest. As in, I don't want to have a blank space in their positions. I want to get:
Element 1 A B C
Element 2 A B C
Element 3 A B C
I tried to give this a try with my array "todelete":
print "#Before Deleting"; print
$todelete[0]; print "\n"; print
$todelete[2]; print "\n"; print
$todelete[3];
for ($count=2; $count<#todelete;
$count=$count+6) { delete
$todelete[$count]; }
print "#After Deleting"; print
$todelete[0]; print "\n"; print
$todelete[2]; print "\n"; print
$todelete[3];$todelete[3];
But, currently, I think it just unitializes my value, because when I print the result, it tells me:
Use of uninitialized value in print
Suggestions?
The function you want is splice.
delete $array[$index] is the same as calling $array[$index] = undef; it leaves a blank space in your array. For your specific problem, how about something like
#array = #array[ grep { $_ % 6 != 2 } 0 .. $#array ];
You can also use grep as a filter:
my $cnt = 0;
#todelete = grep { ++$cnt % 6 != 2 } #todelete;