2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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.*/
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
sed -i $start,${end}d $file
|
||||
sed -i "$start,${end}d" "$file"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue