Matlab - printing selected lines from a text file in new text file - string

I have a text file whose contents are for example:
[1] John where are you bring me copy number = 1 4 5
[2] Hi, Sam what is the cost of your calculator = 200 500 800
[3] Nancy, bring me the no. of copy that I gave you = 4 8 5
[4] Hi, how many litres of milk you have = 10 12 6
[5] Peter, give your copy numb = 23 45 32
& so on.
I am interested in those lines which contains the word ‘copy’. The code below gives me the line number in the text file that contains the word ‘copy’.
fid = fopen(‘my_file.txt', 'r');
C = textscan(fid, '%s', 'Delimiter', '\n');
fclose(fid);
% Search for string ‘copy’ and find all rows that matches it
D = strfind(C{1}, 'copy');
rows = find(~cellfun('isempty', D));
I want to print those lines with the word ‘copy’ in another text file.

First, you need to select the content you want:
C2=C{1}(rows);
fprint can write a comma separated list, which allows to write the file in one line:
fid2=fopen(....
fprintf(fid2,'%s\n',C2{:});
fclose(fid2);

Related

How to delete entire row if any of the cells are blank(or empty) in any row in python

I have the following CSV data:
AAB BT 2 5 5
YUT HYT 89 52 3
JUI 10 2 3
HYIU 2 5 6
YHT JU 25 63 2
In 3rd row(and 4th row), first column(and 2nd column) elements are empty, so delete entire 3rd(and 4th) row. Similarly, the Entire 5th row is empty, also remove the entire 5th row.
My desired output should be:
AAB BT 2 5 5
YUT HYT 89 52 3
YHT JU 25 63 2
I use the following code, but it is not deleating.
import csv
input(r'\\input.csv','r')
output=open(r'Outpur.csv','w',newline="")
writer= csv.writer(output)
for row in csv.reader(input):
if any(field.strip() for field in row):
writer.writerrow(row)
input.close()
output.close()
Firstly, please see the comment from #RomanPerekhrest on your original question. This answer assumes that you are not intending to delete your 6th row of data in your example.
It looks like your line of code:
if any(field.strip() for field in row):
is returning true if any field in the row of data contains an entry.
I suspect that what you want (if I understand your requirement correctly), is for the row of data to be kept if all of the fields in the row contain an entry. Therefore, try changing your code to use:
if all(field.strip() for field in row):
Also, check your debugger to ensure that your code is correctly tokenizing the row by splitting it at each comma in the CSV file.
If field.strip() throws an exception (especially for empty fields), you might need to try employing a string length test instead. Something like:
if all(len(str(field).strip()) > 0 for field in row):
#the following line reads the entire data from your csv file
#list contains list of every fields that are seperated by comma in your
csv file
#of every line
#
data_list=[[s.strip() for s in lines.split(',')] for lines in
open('c:/python34/yourcsv.csv')]
#now you can filter out any list inside your data list
#according to your choice
#such as lists whose length are less than it should be
# lets try it
filtered=[item for item in data_list if not(len(item)<5)]
#now you can overwrite the existing file or simply save it to new file
#and do whatever you want
for item in filtered:
print(item)

How to find the line offset containing a specific number

I am trying to use the following code
put 7 into lFoodID
lineoffset (lFoodID,gArrFood) into tArrFoodLine
to find the line that contain the number 7 in the array below
17 Banana
20 Beans
2 Beef
1 Bread
8 Cabagge
6 Chicken
5 Eggs
15 Ice Cream
3 Mango
7 Pork
18 Rice
4 Salad
19 fried fish
It's returning 1. I know that this is because 17 contains the number 7. I have tried
set the wholeMatches to true
but that does not work either. I believe that regex (^(7) should work but I can figure out how to use regex in lineoffset.
I'm not sure what you're really after and I wonder if your data really look like what you have provided here. I assume that your data are as displayed, but this may lead do a solution that's slightly different from what you really want.
If you want to get the product associated with an index, you can use the following script
put fld 1 into myList
replace space&space with tab in myList
repeat until (tab&tab is not in myList and space&space is not in myList)
replace space&space with space in myList
replace tab&tab with tab in myList
end repeat
split myList by cr and tab
put myList[7] into myProduct
put myProduct
MyProduct contains the product name. Note that you won't need the repeat loop if your data is formatted properly. If you really want to have the index, use this:
put fld 1 into myList
put 7 into myIndex
if word 1 of myList is not myIndex then
put number of lines of char 1 to offset(cr & "7" & space ,myList) of myList into myLine
else
put 1 into myLine
end if
put myLine
MyLine contains the complete record in your list.

matlab string vector / array handling (multiplication u and str2num)

I would like to understand if this is really correct, or if this might be an issue in matlab.
I create an string vector/array via:
>>a=['1','2';'3','4']
It returns:
a =
12
34
Now I would like to convert the content from string to number and multiply this with a number:
>>6*str2num(a)
The result looks like this:
a =
72
204
I don't understand why the comma separated elements (strings) will be concatenated and not separated handled. If you use number instead of strings they will be separated handled. Then it looks like this:
>> a=[1,2;3,4]
a =
1 2
3 4
>> 6*a
ans =
6 12
18 24
I would expect the same results. Any ideas ?
Thanks
Have you read about how string handling is done in MATLAB?
Basically, multiple strings can only be stored as a column vector (of strings). If attempted to store as a row vector, they will be concatenated. This is why strings '1' and '2' are being concatenated, as well as '3' and '4'. Also note, that this is only possible if all resulting strings are of the same length.
I'm not sure what you're trying to do, but if you want to store strings as a matrix (that is, multiple strings in a row), consider storing them in a cell array, for instance:
>> A = {'1', '2'; '3', '4'}
A =
'1' '2'
'3' '4'
>> cellfun(#str2num, A)
ans =
1 2
3 4
I would say that using a cell array as #EitanT suggests would probably be the best solution for you.
However, it is possible to handle strings (or rather characters) like the way you tried by manually inserting spaces and lining up the number of characters.
For example
>> a=['1 2';'3 4']
produces
a =
1 2
3 4
and using
>> 6*str2num(a)
produces
ans =
6 12
18 24
Converting between a matrix and a string using
b=[1,2;3,10000];
num2str(b)
spaces are inserted automatically and the characters are lined up properly. This produces
ans =
1 2
3 10000

is it possible to index character strings pulled from an external .txt file?

I'm in a basic MATLAB college course, and need some help with my code.
theres an external .txt file with names in it, with corresponding numbers assigned to each name. my goal is to place all the first names, last names, and numbers into arrays, find the lowest number in the 'number' array, get the corresponding indexer number, and print the first and last name related with that number.
the text file reads 25 different names and numbers
(i.e.:
Bob
Smith
17
Jane
Doe
23
Bill
Johnson
13
...etc...)
here is my general code so far:
1 clear
2
3 clc
4
5
6 fid1=fopen('facedata.txt','rt');
7
8 for index = 1:1:25
9 firstn(index) = fgetl(fid1);
10 lastn(index) = fgetl(fid1);
11 number(index) = fscanf(fid1,'%f');
12 end
13
14 [distmin,I] = min(dist);
15 fprintf('%5.4f %10s %10.0f', distmin, firstn(I), I);
My hope is for the code to run through, get matlab to recognize '13' as the lowest number, and print 'bill johnson' to the screen, but if I run the code, matlab says there are errors
Subscripted assignment dimension mismatch.' # line 9.
and
Index exceeds matrix dimensions.' # the firstn**(I)** in line 15.
any ideas?? i know this is crazy long, but any help would be appreciated! :]
The command fgetl means read a line from the text file. Therefore your code is reading 2x25 = 50 lines of text. How do you know that your file has this many lines in it? You should read a new line, process it, and repeat until you reach the end of the file:
fid = fopen('fgetl.m');
tline = fgetl(fid);
while ischar(tline)
disp(tline)
tline = fgetl(fid);
end
fclose(fid);
However, this would not do what you want. You should rather use fscanf to read data in the format you want. You want to read two consecutive strings (first name, last name) and an integer number. So you can use
A = fscanf(fid, '%s %s %d', [3 inf]);
to read three items at a time and repeat until the end of the file.
I answered my own question earlier today, but here's what I found if anyone is interested:
you have to index a line of string by using curly brackets instead of straight ones.
i.e.:
for index = 1:1:25
firstname{index} = fgetl(fid1);
end
fprintf('%10s', firstn{index});
fprintf will print whichever number index is supplied.
thanks anyway kavka :]

read complicated .txt file into Matlab

I would like to read a .txt file into Matlab.
One of the columns contains both letters and numbers.
(So I guess one way is to read this column is as string.)
The problem is I also need to find out numbers which are larger than 5 within that column.
e.g. The .txt looks like
12 1
21 2
32 7
11 a
03 b
22 4
13 5
31 6
i.e. Ultimately, I would like to get
32 7
31 6
How can I get it?? Any experts, please help!
You can read the contents of the file into a cell array of strings using TEXTSCAN, convert the strings to numeric values using CELLFUN and STR2NUM (characters like 'a' and 'b' will result in the empty matrix []), remove rows of the cell array that have any empty cells in them, then convert the remaining data into an N-by-2 matrix using CELL2MAT:
fid = fopen('junk.txt','r'); %# Open the file
data = textscan(fid,'%s %s','CollectOutput',true); %# Read the data as strings
fclose(fid); %# Close the file
data = cellfun(#str2num,data{1},'UniformOutput',false); %# Convert to numbers
data(any(cellfun('isempty',data),2),:) = []; %# Remove empty cells
data = cell2mat(data); %# Convert to N-by-2 array
The matrix data will now look like this, given your sample file in the question:
>> data
data =
12 1
21 2
32 7
22 4
13 5
31 6
And you can get the rows that have a value greater than 5 in the second column like so:
>> data(data(:,2) > 5,:)
ans =
32 7
31 6
fid = fopen('txt.txt','r');
Aout = [];
while(1)
[a1,count1] = fscanf(fid,'%s',1);
[a2,count2] = fscanf(fid,'%s',1);
if(count1 < 1 | count2 < 1)
break;
end
if(~isempty(str2num(a2)) & str2num(a2) > 5 & (~isempty(str2num(a1))) )
Aout = [ Aout ; str2num(a1) str2num(a2) ];
end
end
fclose(fid);
Violates the unspoken rule of growing a Matlab variable during a loop, but it's text processing anyway so you probably won't notice the slowness.
Edit: Had too many errors in previous version, had to start fresh.

Resources