import java.io.*; public class Replace { private static boolean verbose = false; private static boolean insensitive = false; private static String pattern1; private static String pattern2; private static int patternLength; private static final String UNIQUE_STRING = "``~~!!@@##$$%%^^&&**(()__++=="; public static void main( String[] args ) { // NB. The JVM automatically converts filenames containing wildcards into a list of filenames. So // when N files match the filename expression, it is as if you typed those N filenames explicitly // in the commandline. // Proces input. if (args.length < 3) { printHelp(); System.exit(0); } int offset = 0; if ( args[0].startsWith("-") ) { offset = 1; if (args.length < 4) { printHelp(); System.exit(0); } } if (offset > 0) { if (args[0].indexOf("i") != -1) {insensitive = true;} if (args[0].indexOf("v") != -1) {verbose = true;} } pattern1 = args[offset]; pattern2 = args[offset + 1]; if (verbose) { System.out.println( "\nOriginal patterns:" + "\n = \"" + pattern1 + "\"" + "\n = \"" + pattern2 + "\"" ); } patternLength = pattern1.length(); // Calculate this only once. if (insensitive) {pattern1 = pattern1.toLowerCase();} // Validate input. if ( patternLength == 0 ) { System.out.println("Error: must not be empty."); System.exit(0); } boolean recurrent = false; if (pattern2.indexOf(pattern1) > -1) {recurrent = true;} if ( (insensitive) && (pattern2.toLowerCase().indexOf(pattern1) > -1) ) {recurrent = true;} if (recurrent) { System.out.println("Error: must not contain ."); System.exit(0); } // Unstuff patterns because of possible character stuffing. pattern1 = unstuff(pattern1); pattern2 = unstuff(pattern2); if (verbose) { System.out.println( "\nPreprocessed patterns:" + "\n = \"" + pattern1 + "\"" + "\n = \"" + pattern2 + "\"" ); } if ( pattern1.indexOf("\n") > -1 ) { System.out.println("Error: must not contain \\n."); System.exit(0); } // Actual processing. for (int i = offset + 2; i < args.length; i++) {processFile(args[i]);} if (verbose) {System.out.println( "#files processed = " + (args.length - 2 - offset) );} System.exit(0); } private static void processFile(String aFilename) { String filename = aFilename; if (verbose) {System.out.print(filename + " : ");} String foutFilename = filename + ".tmp"; File fin = new File(filename); File fout = new File(foutFilename); String line; StringBuffer buf; int index; if ( fin.exists() ) { try { if ( fout.exists() ) { System.out.println("Error: Existence of file: " + foutFilename + " hinders execution."); return; } else { fout.createNewFile(); } } catch (Exception e) { System.out.println( "Error: Unable to create temporary file: " + foutFilename + "\n Exception: " + e.toString() ); return; } try { BufferedReader in = new BufferedReader( new FileReader(fin) ); PrintWriter out = new PrintWriter( new BufferedWriter(new FileWriter(fout)) ); line = in.readLine(); while (line != null) { buf = new StringBuffer( line ); if (insensitive) {index = buf.toString().toLowerCase().indexOf(pattern1);} else {index = buf.toString().indexOf(pattern1);} while (index > -1) { buf.replace(index, index + patternLength, pattern2); if (insensitive) {index = buf.toString().toLowerCase().indexOf(pattern1);} else {index = buf.toString().indexOf(pattern1);} } out.println( buf.toString() ); line = in.readLine(); } in.close(); out.close(); fin.delete(); fout.renameTo(fin); } catch (Exception e) { System.out.println( "Error: " + e.toString() ); return; } } else { System.out.println("Error: File not found:" + fin.getName()); return; } if (verbose) {System.out.println("OK");} } private static void printHelp() { System.out.println( "Replace, version 1.0, by Ronald Koster (http://home.wanadoo.nl/ronald.koster)\n\n" + "A simplified sed (stream editor) version.\n\n" + "Usage: java Replace [-iv] [file2 ...]\n\n" + " : pattern to be replaced\n" + " : new pattern\n" + " : filename of text file to operate on\n" + "[file2 ...] : optional additional filenames\n\n" + "Options\n\n" + " i : match case insensitive\n" + " v : verbose output option\n\n" + "NB. + Patterns may optionally be enclosed by \".\n" + " + They must be enclosed by \" when they contain spaces.\n" + " + They must be literal string patterns. No regular or any other expressions are supported.\n" + " + The following escape sequences are supported:\n" + " \\\" : \" \n" + " \\n : NEWLINE \n" + " \\\\ : \\ \n" + " + NEWLINE is not allowed in .\n" + " + may start with a - in verbose mode only.\n\n" + " + If the last line of a file touched does not end with a NEWLINE, one is appended." ); } private static String unstuff(String aPattern) { if (aPattern.indexOf(UNIQUE_STRING) > -1) { System.out.println("Error: Pattern must not contain: " + UNIQUE_STRING); System.exit(0); } // First replace all \\ with UNIQUE_STRING. aPattern = replace("\\\\", UNIQUE_STRING, aPattern); // Second replace all \n with NEWLINE. aPattern = replace("\\n", "\n", aPattern); // Third relace all UNIQUE_STRING with \. aPattern = replace(UNIQUE_STRING, "\\", aPattern); return aPattern; } private static String replace(String aPat1, String aPat2, String aPattern) { StringBuffer pattern = new StringBuffer(aPattern); int index = pattern.indexOf(aPat1); while (index > -1) { pattern.replace(index, index + aPat1.length(), aPat2); index = pattern.indexOf(aPat1); } return pattern.toString(); } }