I have a file in the following format
USER1
foo
foo
USER2
foo
bar
foo
USER3
bar
bar
I want to find a USER - e.g. USER2 and print the next lines up until the empty line
In Unix I could do something like
cat $FILE | sed -n '/USER2/,/^$/p'
Which would give the output
foo
bar
foo
How can I do similar in Java? I'm OK to read the file, run a for line in loop and find the "USER2" but not sure how I would get the next lines until the empty line?
On StackOverflow it is expected etiquette to post the code you have tried to write, so that answerers can focus on helping you with your specific mistakes, rather than asking for a from-scratch solution. Nevertheless, here you go:
import java.io.BufferedReader;
import java.io.FileReader;
public class SO {
public static void main(String[] args) throws Exception {
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
boolean blank = false;
boolean found = false;
String line;
while ((line = br.readLine()) != null) {
if (line.strip().equals("")) {
blank = true;
found = false;
continue;
} else {
blank = false;
}
if (line.equals("USER1")) {
found = true;
continue;
}
if (!blank && found) {
System.out.println(line);
}
}
}
}
}
Related
i am writing a code where i want to print only comments in a java file , it worked when i have a comments like this
// a comment
but when i have a comment like this :
// /* cdcdf
it will not print "/* cdcdf" , it only prints a blank line
anyone know why this happens ?
here is my code :
package printC;
import java.io.*;
import java.util.StringTokenizer;
import java.lang.String ;
public class PrintComments {
public static void main(String[] args) {
try {
String line;
BufferedReader br = new BufferedReader(new FileReader(args[0]));
while ((line = br.readLine()) != null) {
if (line.contains("//") ) {
StringTokenizer st1 = new StringTokenizer(line, "//");
if(!(line.startsWith("//"))) {
st1.nextToken();
}
System.out.println(st1.nextToken());
}
}
}catch (Exception e) {
System.out.println(e);
}
}
}
You can simplify the code by just looking for the first position of the //. indexOf works fine for this. You don't need to tokenize as you really just want everything after a certain position (or text), you don't need to split the line into multiple pieces.
If you find the // (indexOf doesn't return -1 for "not found"), you use substring to only print the characters starting at that position.
This minimal example should do what you want:
import java.io.*;
import java.util.StringTokenizer;
public class PrintComments {
public static void main(String[] args) throws IOException {
String line; // comment
BufferedReader br = new BufferedReader(new FileReader(args[0]));
while ((line = br.readLine()) != null) {
int commentStart = line.indexOf("//");
if (commentStart != -1) {
System.out.println(line.substring(commentStart));
}
} // /* that's it
}
}
If you don't want to print the //, just add 2 to commentStart.
Note that this primitive approach to parsing for comments is very brittle. If you run the program on its own source, it will happily report //"); as well, for the line of the indexOf. Any serious attempt to find comments need to properly parse the source code.
Edit: If you want to look for other comments marked by /* and */ as well, do the same thing for the opening comment, then look for the closing comment at the end of the line. This will find a /* comment */ when all of the comment is on a single line. When it sees the opening /* it looks whether the line ends with a closing */ and if so, uses substring again to only pick the parts between the comment markers.
import java.io.*;
import java.util.StringTokenizer;
public class PrintComments {
public static void main(String[] args) throws IOException {
String line; // comment
BufferedReader br = new BufferedReader(new FileReader(args[0]));
while ((line = br.readLine()) != null) {
int commentStart;
String comment = null;
commentStart = line.indexOf("//");
if (commentStart != -1) {
comment = line.substring(commentStart + 2);
}
commentStart = line.indexOf("/*");
if (commentStart != -1) {
comment = line.substring(commentStart + 2);
if (comment.endsWith("*/")) {
comment = comment.substring(0, comment.length() - 2);
}
}
if (comment != null) {
System.out.println(comment);
}
} // /* that's it
/* test */
}
}
To extend this for comments that span multiple lines, you need to remember whether you're in a multi-line comment, and if you are keep printing line and checking for the closing */.
StringTokenizer takes a collection of delimiters, not a single string delimiter. so it is splitting on the '/' char. the "second" token is the empty token between the two initial "//".
If you just want the rest of the line after the "//", you could use:
if(line.startsWith("//")) {
line = line.substring(2);
}
Additional to #jtahlborn answer. You can check all of the token by iterating token:
e.g:
...
StringTokenizer st1 = new StringTokenizer(line, "//");
while (st1.hasMoreTokens()){
System.out.println("token found:" + st1.nextToken());
}
...
If you are reading per line, the StringTokenizer don't do much in your code. Try this, change the content of if like this:
if(line.trim().startWith("//")){//true only if líne start with //,aka: comment line
//Do stuff with líne
String cleanLine = line.trim().replace("//"," ");//to remove all // in line
String cleanLine = línea.trim().substring(2,línea.trim().lenght());//to remove only the first //
}
Note: try to always use the trim() to remove all Blanc spaces at begin and end of string.
To split the líne per // use:
líne.split("//")
For more general purpose,check out :
Java - regular expression finding comments in code
I am trying to search the word "hop" from the traceroute output, but somehow its not displaying that line on console. Please let me know where I am going wrong.
Here is my code:
import java.io.*;
public class TestExec {
public static void main(String[] args) {
try {
String[] cmdarray = { "nmap", "--traceroute", "nmap.org" };
Process p = Runtime.getRuntime().exec(cmdarray);
BufferedReader in = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
if (line.contains("hop")) {
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
A few things:
Are you running this in Linux? If you are, you have to run nmap as root. Are you doing so?
I'm not exactly sure what you're trying to look for. In my run of nmap --traceroute nmap.org, there were no lines that contained the word "hop" in lowercase. So even if you are running this program as root, you probably aren't getting very much. I'm fairly certain it doesn't print the word "hop" in lowercase on Windows, either.
I beginner to Java, I want to read and write a string from a text file, I tried with my idea but its not work. It show me an error...
See below my code:
import java.util.*;
import java.io.*;
public class Uptime {
public static void main(String[] args) {
FileWriter fileWriter = null;
try
{
double Oldtime=0;
BufferedReader read=new BufferedReader(new FileReader("C:/eGurkha/agent/sample/UptimeRecord.txt"));
if(read.readLine()!=null)
{
Oldtime=Double.parseDouble(read.readLine());
System.out.println("Old System Time is :"+Oldtime);
}
else
{
Oldtime=0;
}
Process p=Runtime.getRuntime().exec("C:\\eGurkha\\lib\\vmgfiles\\win\\VmgUptimeTest.exe");
BufferedReader rd=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=rd.readLine();
System.out.println(line);
String[] word=line.split("=");
fileWriter=new FileWriter("C:/eGurkha/agent/sample/UptimeRecord.txt");
fileWriter.write(word[1]);
System.out.println("New System Time is :"+word[1]);
System.out.println("String Written");
fileWriter.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
This is the error, which is shown by the above code.
Exception in thread "main" java.lang.NullPointerException
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1008)
at java.lang.Double.parseDouble(Double.java:540)
at com.kavi.tasks.Uptime.main(Uptime.java:17)
Please tell me the idea...
The problem is the code
if(read.readLine()!=null)
{
Oldtime=Double.parseDouble(read.readLine());
You read line (it isn't null) but then you read the next line when try to parse (and the next line is empty).
Use instead
String line=read.readLine();
if(line!=null)
{
Oldtime=Double.parseDouble(line);
if(read.readLine()!=null)
{
Oldtime=Double.parseDouble(read.readLine());
System.out.println("Old System Time is :"+Oldtime);
}
You're reading the line in the if-statement. Then you read the next line in the parseDouble-statement. This is reference is null. So you've to save the line in the if statement.
String line = null;
if((line = read.readLine()) != null) {
double time = Double.parseDouble(line);
...
}
Try to Pass the String in the if statement ,so that the compile would know that which type of object he needs to pass.
if(String=....
.....){
}
problem is with
if(read.readLine()!=null)
{
Oldtime=Double.parseDouble(read.readLine());
System.out.println("Old System Time is :"+Oldtime);
}
readLine() internally calls lineNumber++ which means you go to next line of your file when you call this. Instead use
if((line = read.readLine()) != null)
{
Oldtime=Double.parseDouble(line);
System.out.println("Old System Time is :"+Oldtime);
}
I have written a class to ping an IP address that i provide, but it won't return anything.
I tried adding a few markers to see where it goes wrong, but not even that worked...
I have a gui interface and I use a Label to write my data out (the same format worked before with a string), here is the code. There were certain lines that i did or did not want, hence the "relevant" integer, you may ignore it. This should run on ubuntu 13.10.
public static ArrayList<String> PingIpAddr(String string) throws IOException{
String s = new String();
int relevant =0;
ArrayList<String> List = new ArrayList<String>();
List.add("it happens \n");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(new ProcessBuilder(string).start().getInputStream()));
while ((s = stdInput.readLine()) != null){
List.add("does this happen? \n");
relevant++;
if( (relevant == 2) || (relevant == 3) || (relevant == 4) || (relevant == 5) || (relevant == 6) || (relevant == 9) ){List.add(s + "\n");
List.add("or this? \n");}} //end of while
List.add("This must happen! \n");
return List;} //end of Ping
and if this would work, here is where it would be implemented:
String test;
test = PingIp.testPingIpAddr("ping -c 5 4.2.2.2").toString();
TeltonikaPing.setWrapText(true);
TeltonikaPing.setText(test);
Strangely it doesn't give back a sigle line. Maybe I'm just missing something very basic?:/
the main issue is caused by the fact ping has a delay in most cases, try making use of stdInput.ready().
I would probably pass this to ProcessBuilder: new ProcessBuilder("myCommand", "myArg1", "myArg2"); split out the command ping from its parameters.
as in - http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
I hope this helps (:
Edit -- (this works below)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Pinger
{
public static List<String> PingIpAddr(String ip) throws IOException
{
ProcessBuilder pb = new ProcessBuilder("ping", ip);
//ProcessBuilder pb = new ProcessBuilder("ping", "-c 5", ip);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(pb.start().getInputStream()));
while (!stdInput.ready())
{
// custom timeout handling
}
String line;
ArrayList<String> output = new ArrayList<>();
while ((line = stdInput.readLine()) != null)
{
output.add(line);
}
return output;
}
public static void main(String[] args) throws IOException
{
List<String> lines = Pinger.PingIpAddr("127.0.0.1");
for (String line : lines)
{
System.out.println(line);
}
}
}
I found a nother solution, that lets me enter how long i want the Ping to be.
How to run PING command and get ping host summary?
if anyone else needs to incorporate it into a GUI :)
I have a text file admin.dat which looks like this:
blackranger|sdasdasdasd23123|1000
blueranger|sdasdasdasdwhhh22|1000
brownranger|lppsadospd123|1000
I am trying to read every line, using | as my delimiter and outputting to the console every section.
Code:
package testing;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class Testing {
public static void main(String[] args) {
Scanner filereader = null;
try {
filereader = new Scanner(new File("./src/testing/players.dat"));
String data;
while(filereader.hasNextLine()) {
String foo = "abc|123|a213";
String[] bar = foo.split("|");
for (int i = 0; i < 3; i++) {
System.out.println(bar[i]);
}
}
} catch (FileNotFoundException e) {
System.out.println("File not found");
} catch (IOException e) {
System.out.println("Error while reading file");
} finally {
if (filereader != null) {
filereader.close();
}
}
}
}
Expected Outcome:
blackranger
sdasdasdasd23123
1000
blueranger
sdasdasdasdwhhh22
1000
brownranger
lppsadosph123
1000
Actual Outcome:
a // infinite loop
b
a
b
a
b
a
b
a
b
Why am I getting an infinite loop which prints a b forever?
You should escape the character | because it has special meaning in regex
foo.split("\\|");
But firstly, assign foo with value that you read from the file, not by hard-coded it:
String foo = filereader.nextLine();
You never read from the fileReader inside the while loop, so while(filereader.hasNextLine()) will always be true, and it makes sense that the loop will never end. What surprised me is that it looked like you had code that did read from the fileReader inside of the loop but commented it out. Why?
Solution: don't do this. Make sure to change the test condition inside the while loop, else the while loop will never end.
String foo = filereader.nextLine();
String[] bar = foo.split("\\|");
instead of
String foo = "abc|123|a213";
String[] bar = foo.split("|");