cutting column from file in java - java

I've searched and can't find my question.
I've saved file with linux output ls -l which content is:
drwxr-xr-x 2 usr usr 4096 Jan 20 17:49 file1
drwxrwxr-x 4 usr usr 4096 Jan 20 18:00 file2
drwx------ 2 usr usr 4096 Feb 3 08:48 catalog1
And I want to leave for example only eighth column with hour, and cut off rest of it. What should I do? I'm very beginner with java and programming.

You can use a regular expression to match the timestamp (since it's guaranteed that a time-like value will not appear in any of the other fields). Something like:
// Populate this with the output of the ls -l command
String input;
// Create a regular expression pattern to match.
Pattern pattern = Pattern.compile("\\d{2}:\\d{2}");
// Create a matcher for this pattern on the input string.
Matcher matcher = pattern.matcher(input);
// Try to find instances of the given regular expression in the input string.
while (matcher.find()){
System.out.println(matcher.group());
}
To retrieve any arbitrary column, you can opt to write a regular expression for whichever column you're trying to retrieve, or you may wish to just split each row on the space character, then select by index. For example, to get all of the filesizes:
String input;
String[] inputLines = input.split("\n");
for (String inputLine : inputLines) {
String[] columns = inputLine.split(" ");
System.out.println(columns[4]); // Where 4 indicates the filesize column
}

You need to use StringTokenizer to extract out the exact information that you are looking for. Try the following code:
String value = "drwxr-xr-x 2 usr usr 4096 Jan 20 17:49 file1\n"+
"drwxrwxr-x 4 usr usr 4096 Jan 20 18:00 file2\n"+
"drwx------ 2 usr usr 4096 Feb 3 08:48 catalog1";
StringBuffer sBuffer = new StringBuffer(10);
StringTokenizer sTokenizer = new StringTokenizer(value,"\n");
while (sTokenizer.hasMoreTokens())
{
String sValue = sTokenizer.nextToken();
StringTokenizer sToken = new StringTokenizer(sValue," ");
int counter = 0;
while (sToken.hasMoreTokens())
{
String token = sToken.nextToken();
counter++;
if (counter == 8)//8 is the column that you want to leave.
{
sBuffer.append(token+"\n");
break;
}
}
}
System.out.println(sBuffer.toString());

Related

Java scanner delimiter causes my integer to not be read properly

So I'm creating a scanner to read off of a simple text file:
import java.io.*;
import java.util.Scanner;
public class Weather {
public static void main(String[] args) throws FileNotFoundException {
int a;
File weatherData = new File("C:\\Users\\taddi\\eclipse-workspace\\COS_160_ASSIGNMENT_10\\src\\PortlandWeather1941to2018.txt");
Scanner scnr = new Scanner(weatherData);
scnr.useDelimiter("//");
int totalCount = scnr.nextInt();// this reads the number at the beginning and uses it so I know how many times to run the loop
String throwAway1 = scnr.nextLine();//these statement are used to throw a way the rest of line 1, and all of line 2 and 3
String throwAway2 = scnr.nextLine();
String throwAway3 = scnr.nextLine();
int[] month = new int[totalCount];
int[] day = new int[totalCount];
int[] year = new int[totalCount];
int[] tmax = new int[totalCount];
int[] tmin = new int[totalCount];
for(a = 0; a < totalCount; a ++) {
month[a] = scnr.nextInt();
System.out.println(month[a]);
day[a] = scnr.nextInt();
System.out.println(day[a]);
year[a] = scnr.nextInt();
tmax[a] = scnr.nextInt();
tmin[a] = scnr.nextInt();
}
}
}
The first part of the text file is an integer I'm trying to read. For some reason, it only reads that integer when I comment out the scnr.useDelimiter("//"); line, otherwise I get an InputMismatchException
I'd love to just get rid of all the unnecessary words and slashes in the text file but that wouldn't satisfy the assignment. What's going wrong with the delimiter? How do I read the integer?
Your delimiter is a string, and it will not work in your use case the way you want.
I assume your sample data is like this (ignoring the header lines) ...
01/01/1941 38 25
01/02/1941 32 20
... so you are looking to get each number - the date elements and the tmax/tmin values - so a single delimiter character of '/' would only break up the date.
For example:
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter("/");
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
outputs the following ...
01
01
1941 38 25
01
02
1941 32 20
showing that it splits on the date d/m/y slashes, but the year and tmax and tmin are bundled together.
Adjusting the scanner to use a Pattern delimiter allows us to split on the slashes and the spaces.
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter(Pattern.compile("[/ ]+"));
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
}
giving the output I think you want:
01
01
1941
38
25
01
02
1941
32
20
However, note that in my example data I have trailing whitespace on each line and they are thus also returned as empty String tokens. If I was scanning for nextInt() I would get an java.util.InputMismatchException error. Depending on the exact formatting of your input you may need to cater for that.

How to get specific substring with option vale using java

I have a string and from this string, I want to get password file path which is identified by an option (-sn).
String s = "msqlsum81pv 0 0 25 25 25 2 -sn D:\workdir\PV_81\config\sum81pv.pwf -C 5000"
above line is a configuration line which can be with either -sn or -n.
please suggest how to get D:\workdir\PV_81\config\sum81pv.pwf line from above string or the string may be with quoted string.
below is my code which check only -sn option but I want to check with either -sn or -n .
if ( s.matches( "^\\s*msql.*$" ) )
{
StringTokenizer st = new StringTokenizer( s, " " );
while ( st.hasMoreTokens() )
{
if ( st.nextToken().equals( "-sn" ) )
{
pwf = st.nextToken();
}
}
}
I want to use StreamTokenizer instead of StringTokenizer class and get D:\workdir\PV_81\config\sum81pv.pwf
this path may be containing spaces in it.
String s = "msqlsum81pv 0 0 25 25 25 2 -sn D:\workdir\PV_81\config\sum81pv.pwf -C 5000"
if ( s.matches( "^\\s*msql.*$" ) )
{
StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(s));
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF)
{
System.out.println(tokenizer.sval);
}
}
You should use a regular expression to detect that option in a more general way. If you want a quick fix you can use the OR operator in your if but each time that new operations appear your if will grow and it's a bad idea.
if ( s.matches( "^\\s*msql.*$" ) )
{
StringTokenizer st = new StringTokenizer( s, " " );
while ( st.hasMoreTokens() )
{
string token = st.nextToken();
if ( token.equals( "-sn" ) || token.equals("-n" ) )
{
pwf = st.nextToken();
}
}
}
As pointed out on this answer, you could use any good command line arguments parser, like:
Commons CLI
http://commons.apache.org/cli/
Java Gems
http://code.google.com/p/javagems/
JArgs
http://jargs.sourceforge.net/
GetOpt
http://www.urbanophile.com/arenn/hacking/download.html
More Q&A on command like arguments: this and this.
Use regex, as given in this example
public static void main(String[] args) {
System.out.println(findString("msqlsum81pv 0 0 25 25 25 2 -sn D:\\workdir\\PV_81\\config\\sum81pv.pwf -C 5000"));
System.out.println(findString("msqlsum81pv 0 0 25 25 25 2 -s D:\\workdir\\PV_81\\config\\sum81pv.pwf -C 5000"));
System.out.println(findString("msqlsum81pv 0 0 25 25 25 2 -sn \"D:\\workdir\\PV_81\\config\\sum81pv.pwf\" -C 5000"));
System.out.println(findString("msqlsum81pv 0 0 25 25 25 2 -s \"D:\\workdir\\PV_81\\config\\sum81pv.pwf\" -C 5000"));
}
private static String findString(String inputCommand) {
String path;
if(inputCommand.matches(".*(-sn|-s) \"+.*")) {
path = inputCommand.replaceAll(".*(-sn|-s) \"?([^\"]*)?.*", "$2");
} else {
path = inputCommand.replaceAll(".*(-sn|-s) \"?([^ ]*)?.*", "$2");
}
return path;
}
O/P
D:\\workdir\\PV_81\\config\\sum81pv.pwf
D:\\workdir\\PV_81\\config\\sum81pv.pwf
D:\\workdir\\PV_81\\config\\sum81pv.pwf
D:\\workdir\\PV_81\\config\\sum81pv.pwf
Edit: note you might need to modify this if the path could contain whitespace. Then you might want to check until -C or allways escape the whole path and check when the next " will appear.
definitely use regular expression,my answer is below
public static String extractString(final String input) {
String ret = null;
final Pattern pattern = Pattern.compile("(..\\\\.*\\.*?)(?:\"?)\\p{Space}");
final Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
ret = matcher.group(1);
}
return ret;
}
basically, i search from first '\' to first space after dot, and extract this substring, use capture group to filter quote mark if there is one
therefore it doesnt matter where this substring is in this cmd string

Data evaluation from text file

I need some help. I dont know how to solve my problem.
I have text file in this format:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
I need to count the numbers for every person. The output should be "personx = 50" etc.
I can not use my old system where I knew there is 10 people. So I had 10 variables and I just went through the file with scanner and checked if line starts with "personx" then count the number to variable personx etc. I dont want to use these variables now. I dont want to change code after every new person.
How to solve this? I want to have this output sorted from highest to lowest:
personi = 55
personx = 50
persony = 12
personz = 2
Is that possible without using variables personi, personx, persony, personz ? My idea was to go through the file and scan the names. Save the name into an array and add another name into an array if that name is not in the array yet. So I will have the names.
Next I will scan the file again and check for the name and number. Check name + number and then save the number into another array on the same possition as the name in the first array. So I will have
Names[0] = "personi";
Count[0] = 55;
Names[1] = "personx";
Count[1] = 50;
And then I will just print these two arrays with for cycle.
I dont think that it is the best solution. How would you do it? Is there something better/faster/easier ? And how to solve that Sorting?
Thank you for your time.
You can us Map<String,Integer>
In this case i used TreeMap which will sort everything for you. If you dont need sorting then just use HashMap instead of TreeMap.
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person = new String[2];
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
Output:
personi = 55
personx = 50
persony = 12
personz = 2
1) Can I use this on file where line is not in my format but it has for example.. this format ? "personx bla bla 25" ? Is it possible to convert it too? how?
Yes you can create method which will do it for you. You can use either string splits or some regex.
2) Why is there String [] person = new String[2]; ?
Mistake, it should be String[1]. Corrected now
3) what is String line = ""; ?
It is just new String where i'm storing every line that i read from file. As you can see, im assigning reder.readLine() in while loop. After that im just splitting it.
EDIT:
Changed code so person can have multiple params but will take only first as name and last as number.
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person;
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[person.length-1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx asdasdas dasd asd a 25
personz 2
persony asd asd asd a 5
persony 7
personi 55
personx 25
output:
personi = 55
personx = 50
persony = 12
personz = 2

java splitting a string by line \n not working

So I have a string which is from a text file, essentially the text file is just 5 lines which read:
x=1
y=15
z=128
topx=100
leftx=150
label= this is a test
I am able to get the split to work once which separates via the '=' sign, but when I try to split the string again by \n nothing works, I have tried using "\r?\n", line.Separator etc. but the string value always stays the same, basically the 5 lines without the characters before the = sign. How would I pull out the individual lines to assign variables to?
Here is the code I have, basically the println is to try and see if I can get the first value '1' to list separate from the rest of the lines.
public static void main(String[] a) {
15 draw d = new draw();
16 Read r = new Read();
17 String m = r.doRead("variables.txt");
18
19 String[] ss = new String[5];
20 ss = m.split("\n");
21
22 String[] kv= new String[5];
23 for (int i=0; i<ss.length; i++) {
24 kv = ss[i].split("=");
25 String eol = System.getProperty("line.seperator");
26 String test = kv[1];
27 String[] split = new String[5];
28 split = test.split("\n");
29
30
31
32
33 String first = split[0];
34 //String second = split[1];
35 //String third = split[2];
36 //String fourth = split[3];
37 //String fifth = split[4];
38 System.out.println(first);
39 }
When every line looks like
x=1 y=15 z=128 topx=100 leftx=150 label= this is a test
you should first split at a whitespace to get 5 parts (x=1, y=15, ...) and then at = to get the "key" and "value" part of each part.
check this out:
String s = "x=1\ny=15\nz=128\ntopx=100\nleftx=150\nlabel= this is a test";
String[] ss = s.split("\n");
System.err.println( Arrays.asList(ss[0].split("=")) );

Find a pair of string at integer and subtract, java

I have a string which contains a value:
12345 5
54321 4
98765 10
The first value is a number, the second value is a count. The string value is obtained by this code:
for(ClusterListBean bean : clusterList) {
line += bean.getMSISDN()+"\t"+bean.getRewardCount()+"\n";
}
Now I am reading a file which has same contents but different count value.
This is accomplished by:
BufferedReader ln = FileCreatorUtil.readFile(configFileUtil.prevFile().getFileDir()+prevFile.clusterPrevFile().getFileName());
Now what I want to do is to search for a number value, get the count paired with it, and subtract the count. Example:
BufferedReader ln contents:
12345 5
54321 4
98765 10
String line contents:
12345 7
54321 9
98765 15
Output should be:
12345 2
54321 5
98765 5
Put your data into a HashMap where MSISDN is key and count is value. Reading second file consult that map and subtract the value.
Why don't you put your "Strings" in a hashmap?
Map<String,Integer> map = new HashMap<String,Integer>();
for(ClusterListBean bean : clusterList) {
map.put(bean.getMSISDN(),bean.getRewardCount());
}
then read your file:
BufferedRead ln = null;
try{
ln = new BufferedReader(new FileReader(configFileUtil.prevFile().getFileDir()+prevFile.clusterPrevFile().getFileName()));
String line;
while((line=br.readLine())!=null){
String[] linesplit = line.split("\\t");
if (map.containsKey(linesplit[0])){
//do whatever you need with something like:
System.out.println(map.get(linesplit[0])-Integer.parseInt(linesplit[1]));
}
}
ln.close();
}catch(IOException e){
e.printStackTrace();
}

Categories