2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,3 +1,11 @@
The task is to demonstrate how to remove a specific line or a number of lines from a file. This should be implemented as a routine that takes three parameters (filename, starting line, and the number of lines to be removed). For the purpose of this task, line numbers and the number of lines start at one, so to remove the first two lines from the file <tt>foobar.txt</tt>, the parameters should be: <tt>foobar.txt</tt>, <tt>1</tt>, <tt>2</tt>
;Task:
Remove a specific line or a number of lines from a file.
Empty lines are considered and should still be counted, and if the specified line is empty, it should still be removed. An appropriate message should appear if an attempt is made to remove lines beyond the end of the file.
This should be implemented as a routine that takes three parameters (filename, starting line, and the number of lines to be removed).
For the purpose of this task, line numbers and the number of lines start at one, so to remove the first two lines from the file <tt>foobar.txt</tt>, the parameters should be: <tt>foobar.txt</tt>, <tt>1</tt>, <tt>2</tt>
Empty lines are considered and should still be counted, and if the specified line is empty, it should still be removed.
An appropriate message should appear if an attempt is made to remove lines beyond the end of the file.
<br><br>

View file

@ -0,0 +1,242 @@
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' Remove File Lines V1.0 '
' '
' Developed by A. David Garza Marín in VB-DOS for '
' RosettaCode. November 30, 2016. '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
'OPTION _EXPLICIT ' For QB45
'OPTION EXPLICIT ' For VBDOS, PDS 7.1
' SUBs and FUNCTIONs
DECLARE FUNCTION DeleteLinesFromFile% (WhichFile AS STRING, Start AS LONG, HowMany AS LONG)
DECLARE FUNCTION FileExists% (WhichFile AS STRING)
DECLARE FUNCTION GetDummyFile$ (WhichFile AS STRING)
DECLARE FUNCTION ErrorMessage$ (WhichError AS INTEGER)
DECLARE FUNCTION CountLines& (WhichFile AS STRING)
DECLARE FUNCTION YorN$ ()
' Var
DIM iOk AS INTEGER, iErr AS INTEGER, lStart AS LONG, lHowMany AS LONG, lSize AS LONG
DIM sFile AS STRING
' Const
CONST ProgramName = "RemFLine (Remove File Lines) Enhanced V1.0"
' ----------------------------- Main program cycle --------------------------------
CLS
PRINT ProgramName
PRINT
PRINT "This program will remove as many lines of a text file as you state, starting"
PRINT "with the line number you also state. If the starting line number is beyond"
PRINT "total lines in the text file stated, then the process will be aborted. If the"
PRINT "quantity of lines stated to be deleted is beyond the total lines in the text"
PRINT "file, the process also will be aborted. The program will give you a message"
PRINT "if everything ran ok or if any error happened. Includes a function to count"
PRINT "how many lines has the intended file."
DO
PRINT
INPUT "Please, type the name of the file"; sFile
sFile = LTRIM$(RTRIM$(sFile))
IF sFile <> "" THEN
lSize = CountLines&(sFile)
IF lSize > 0 THEN
PRINT "Delete starting on which line (Default=1, Max="; lSize; ")";
INPUT lStart
IF lStart = 0 THEN lStart = 1
IF lStart < lSize THEN
PRINT "How many lines do you want to remove (Default=1, Max="; (lSize - lStart) + 1; ")";
INPUT lHowMany
IF lHowMany = 0 THEN lHowMany = 1
IF lHowMany + lStart <= lSize THEN
iOk = DeleteLinesFromFile%(sFile, lStart, lHowMany)
ELSE
iOk = 1
END IF
ELSE
iOk = 2
END IF
ELSEIF lSize = -1 THEN
iOk = 3
ELSE
iOk = 4 ' The file is not a text file
END IF
ELSE
iOk = 5 ' Null file name not allowed
END IF
PRINT
PRINT ErrorMessage$(iOk)
PRINT "Do you want to try again? (Y/N)"
LOOP UNTIL YorN$ = "N"
'----------------End of Main program Cycle ----------------
END
FileError:
iErr = ERR
RESUME NEXT
FUNCTION CountLines& (WhichFile AS STRING)
' Var
DIM iFile AS INTEGER
DIM l AS LONG, li AS LONG, j AS LONG, lFileSize AS LONG, lLines AS LONG
DIM sLine AS STRING, strR AS STRING
' This function will count how many lines has the file
IF FileExists%(WhichFile) THEN
strR = CHR$(13)
li = 1
iFile = FREEFILE
sLine = SPACE$(128)
lLines = 0
OPEN WhichFile FOR BINARY AS #iFile
lFileSize = LOF(iFile)
DO
IF (LOC(iFile) + LEN(sLine)) > lFileSize THEN
sLine = SPACE$(lFileSize - LOC(iFile))
END IF
IF LEN(sLine) > 0 THEN
GET #iFile, , sLine
GOSUB AnalizeLine
END IF
LOOP UNTIL LEN(sLine) < 128
CLOSE iFile
ELSE
lLines = -1
END IF
CountLines& = lLines
EXIT FUNCTION
AnalizeLine:
li = 1
DO
l = INSTR(li, sLine, strR)
IF l > 0 THEN
lLines = lLines + 1
li = l + 1
END IF
LOOP UNTIL l = 0
RETURN
END FUNCTION
FUNCTION DeleteLinesFromFile% (WhichFile AS STRING, Start AS LONG, HowMany AS LONG)
' Var
DIM lCount AS LONG, iFile AS INTEGER, iFile2 AS INTEGER, lhm AS LONG, iError AS INTEGER
DIM sLine AS STRING, sDummyFile AS STRING
IF FileExists%(WhichFile) THEN
sDummyFile = GetDummyFile$(WhichFile)
' It is assumed a text file
iFile = FREEFILE
OPEN WhichFile FOR INPUT AS #iFile
iFile2 = FREEFILE
OPEN sDummyFile FOR OUTPUT AS #iFile2
lhm = 0
DO WHILE NOT EOF(iFile)
LINE INPUT #iFile, sLine
lCount = lCount + 1
IF lCount >= Start AND lhm < HowMany THEN
lhm = lhm + 1
ELSE
PRINT #iFile2, sLine
END IF
LOOP
CLOSE iFile2, iFile
' Check if everything went ok or not
iError = 0
IF lCount < Start THEN
iError = 2 ' Full file is shorter than the start line stated,
' process will be aborted.
ELSEIF lhm < HowMany THEN
iError = 1 ' File was shorter than lines requested to be removed,
' process will be aborted.
END IF
IF iError > 0 THEN
KILL sDummyFile ' Process aborted
ELSE
KILL WhichFile
NAME sDummyFile AS WhichFile
END IF
ELSE
iError = 3 ' The file doesn't exist. The process is aborted.
END IF
DeleteLinesFromFile% = iError
END FUNCTION
FUNCTION ErrorMessage$ (WhichError AS INTEGER)
' Var
DIM sError AS STRING
SELECT CASE WhichError
CASE 0: sError = "Everything went Ok. Lines removed from file."
CASE 1: sError = "File is shorter than the number of lines stated to remove. Process aborted."
CASE 2: sError = "Whole file is shorter than the starting point stated. Process aborted."
CASE 3: sError = "File doesn't exist. Process aborted."
CASE 4: sError = "The file doesn't seem to be a text file. Process aborted."
CASE 5: sError = "You need to provide a valid file name, please."
END SELECT
ErrorMessage$ = sError
END FUNCTION
FUNCTION FileExists% (WhichFile AS STRING)
' Var
DIM iFile AS INTEGER
DIM iItExists AS INTEGER
SHARED iErr AS INTEGER
ON ERROR GOTO FileError
iFile = FREEFILE
iErr = 0
OPEN WhichFile FOR BINARY AS #iFile
IF iErr = 0 THEN
iItExists = LOF(iFile) > 0
CLOSE #iFile
IF NOT iItExists THEN
KILL WhichFile
END IF
END IF
ON ERROR GOTO 0
FileExists% = iItExists
END FUNCTION
FUNCTION GetDummyFile$ (WhichFile AS STRING)
' Var
DIM i AS INTEGER, j AS INTEGER
' Gets the path specified in WhichFile
i = 1
DO
j = INSTR(i, WhichFile, "\")
IF j > 0 THEN i = j + 1
LOOP UNTIL j = 0
GetDummyFile$ = LEFT$(WhichFile, i - 1) + "$dummyf$.tmp"
END FUNCTION
FUNCTION YorN$ ()
' Var
DIM sYorN AS STRING
DO
sYorN = UCASE$(INPUT$(1))
IF INSTR("YN", sYorN) = 0 THEN
BEEP
END IF
LOOP UNTIL sYorN = "Y" OR sYorN = "N"
YorN$ = sYorN
END FUNCTION

View file

@ -0,0 +1,19 @@
using System;
using System.IO;
public class Rosetta
{
/* C# 6 version:
public static void Main() => RemoveLines("foobar.txt", start: 1, count: 2);
*/
public static void Main() {
RemoveLines("foobar.txt", start: 1, count: 2);
}
static void RemoveLines(string filename, int start, int count = 1) {
//Reads and writes one line at a time, so no memory overhead.
File.WriteAllLines(filename, File.ReadAllLines(filename)
.Where((line, index) => index < start - 1 || index >= start + count - 1));
}
}

View file

@ -0,0 +1,29 @@
defmodule RC do
def remove_lines(filename, start, number) do
File.open!(filename, [:read], fn file ->
remove_lines(file, start, number, IO.read(file, :line))
end)
end
defp remove_lines(_file, 0, 0, :eof), do: :ok
defp remove_lines(_file, _, _, :eof) do
IO.puts(:stderr, "Warning: End of file encountered before all lines removed")
end
defp remove_lines(file, 0, 0, line) do
IO.write line
remove_lines(file, 0, 0, IO.read(file, :line))
end
defp remove_lines(file, 0, number, _line) do
remove_lines(file, 0, number-1, IO.read(file, :line))
end
defp remove_lines(file, start, number, line) do
IO.write line
remove_lines(file, start-1, number, IO.read(file, :line))
end
end
[filename, start, number] = System.argv
IO.puts "before:"
IO.puts File.read!(filename)
IO.puts "after:"
RC.remove_lines(filename, String.to_integer(start), String.to_integer(number)

View file

@ -0,0 +1,35 @@
(context 'ABC)
(define (remove-lines-from-a-file filename start num)
(setf new-content "")
(setf row-counter 0)
(setf start-delete-row start)
(setf end-delete-row (+ start num -1))
(setf file-content (read-file filename))
(setf max-rows (length (parse file-content "\n" 0)))
(cond
((<= start 0)
(println "Start line must be >= 1. Value passed: " start))
((<= num 0)
(println "# of lines to remove must be >= 1. Value passed: " num))
((> start max-rows)
(println "Start line must be <= " max-rows ". Value passed: " start))
((> end-delete-row max-rows)
(println "Not so much lines available to be removed. Max " (- max-rows start-delete-row) ". Value passed: " num))
(true
(dolist (row (parse file-content "\n" 0))
(++ row-counter)
(if (or (< row-counter start-delete-row) (> row-counter end-delete-row))
(setf new-content (append new-content row "\n"))
)
)
(write-file filename new-content)
)
)
)
(context 'MAIN)
(ABC:remove-lines-from-a-file "foobar.txt" 8 3)
(exit)

View file

@ -0,0 +1,69 @@
; Contents of file 'input.txt' before deletion of lines :
;
; cat
; dog
; giraffe
; lion
; mouse
; pig
; tiger
; zebra
EnableExplicit
#Output$ = "output.txt"; insert path to temporary output file
Procedure RemoveLines(Input$, StartLine, NbLines)
Protected lineCount = 0
Protected endline = StartLine + NbLines - 1
Protected row$
If Not ReadFile(0, Input$)
PrintN("Error opening input file")
ProcedureReturn
EndIf
If Not CreateFile(1, #Output$)
PrintN("Error creating output file")
CloseFile(0)
ProcedureReturn
EndIf
While Not Eof(0)
row$ = ReadString(0)
lineCount + 1
If lineCount < StartLine Or lineCount > endLine
WriteStringN(1, row$)
EndIf
Wend
If endLine > lineCount
PrintN("Attempted to remove lines beyond the end of the file")
; but still allow removal of lines (if any) up to the end of the file
EndIf
CloseFile(0)
CloseFile(1)
If Not DeleteFile(Input$)
PrintN("Unable to delete input file so output file can be renamed")
ProcedureReturn
EndIf
If Not RenameFile(#Output$, Input$)
PrintN("Unable to rename output file")
EndIf
EndProcedure
Define fInput$
If OpenConsole()
; delete lines 2,3 amnd 4 of 'input.txt'
fInput$ = "input.txt"; insert path to input file
RemoveLines(fInput$, 2, 3)
PrintN("")
PrintN("Press any key to close the console")
Repeat: Delay(10) : Until Inkey() <> ""
CloseConsole()
EndIf

View file

@ -1,23 +1,23 @@
/*REXX program reads/writes a specified file and delete(s) specified record(s)*/
parse arg iFID ',' N ',' many /*input FID, start of delete, how many.*/
if iFID='' then call er "no input fileID specified." /*oops.*/
if N='' then call er "no start number specified." /*oops.*/
if many='' then many=1 /*Not specified? Assume delete 1 line.*/
stop=N+many-1 /*calculate high end of delete range.*/
oFID=iFID'.$$$' /*temp name (fileID) of the output file*/
#=0 /*the count (so far) of records written*/
do j=1 while lines(iFID)\==0 /*J is the record# (line) being read.*/
@=linein(iFID) /*read a record (line) from input file.*/
if j>=N & j<=stop then iterate /*if it's in the range, then ignore it.*/
call lineout oFID,@; #=#+1 /*write record (line);, bump write cnt.*/
end /*j*/ /* [↑] by ignoring it is to delete it.*/
j=j-1 /*adjust J (because of DO loop advance)*/
/*REXX program reads and writes a specified file and delete(s) specified record(s). */
parse arg iFID ',' N "," many . /*input FID, start of delete, how many.*/
if iFID='' then call er "no input fileID specified." /*oops.*/
if N='' then call er "no start number specified." /*oops.*/
if many='' then many=1 /*Not specified? Assume delete 1 line.*/
stop=N+many-1 /*calculate high end of delete range.*/
oFID=iFID'.$$$' /*temp name (fileID) of the output file*/
#=0 /*the count (so far) of records written*/
do j=1 while lines(iFID)\==0 /*J is the record# (line) being read.*/
@=linein(iFID) /*read a record (line) from input file.*/
if j>=N & j<=stop then iterate /*if it's in the range, then ignore it.*/
call lineout oFID,@; #=#+1 /*write record (line);, bump write cnt.*/
end /*j*/ /* [↑] by ignoring it is to delete it.*/
j=j-1 /*adjust J (because of DO loop advance)*/
if j<stop then say "The number of lines in file is less than the range given."
$='"' /*handle cases of blanks in the FID(s).*/
'ERASE' $ || iFID || $ /*erase the original file.*/
'RENAME' $ || oFID || $ $ || iFID || $ /*rename " new " */
say 'file ' iFID " had" j 'record's(j)", it now has" # 'record's(w)"."
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────one─liner subroutines─────────────────────*/
er: say; say '***error!***'; say; say arg(1); say; exit 13
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plurals.*/
$='"' /*handle cases of blanks in the FID(s).*/
'ERASE' $ || iFID || $ /*erase the original file. */
'RENAME' $ || oFID || $ $ || iFID || $ /*rename " new " to original. */
say 'file ' iFID " had" j 'record's(j)", it now has" # 'record's(w)"."
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
er: say; say '***error***'; say; say arg(1); say; exit 13
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*pluralizer.*/

View file

@ -1,6 +1,6 @@
#!/bin/sh
error() {
echo "$*"
echo >&2 "$0: $*"
exit 1
}
@ -8,8 +8,9 @@ error() {
file=$1
start=$2
end=$3
count=$3
end=`expr $start + $count - 1`
[ -f $file ] || error "$file does not exist"
[ -f "$file" ] || error "$file does not exist"
sed $start,${end}d $file >/tmp/$$ && mv /tmp/$$ $file
sed "$start,${end}d" "$file" >/tmp/$$ && mv /tmp/$$ "$file"

View file

@ -1 +1 @@
sed -i $start,${end}d $file
sed -i "$start,${end}d" "$file"