How do you delete one line from a [file]? What kind of file are you talking about? There aren't, in general, lines in [MP3] files, or [GIF] files, etc. In fact, most operating systems today don't have operating system calls that deal in lines. Instead, they come with what I have named, at times, "meta-read" functions - pieces of code which read in chunks of bytes from a file, and then, depending on the function's intention, add some code implementing a common interpretation of some of those bytes. Most people, asking this particular question, are ''really'' asking "Assume that I have a plain, traditional, text file - containing 7 bit [ASCII] characters, where newline character indicate the end of a "line". How can I delete one of those "lines" ." And honestly, I really believe that's what is being asked. So the following attempts to address that specific interpretation of this question. ----- Here's an example: set tmpname /tmp/something set source [open $filename] set destination [open $tmpname w] set content [read $source] close $source set lines [split $content \n] set lines_after_deletion \ [lreplace $lines $line_number_to_remove $line_number_to_remove] puts -nonewline $destination [join $lines_after_deletion \n] close $destination file rename -force $tmpname $filename Note, however, that in both of these cases, what you are doing are reading the entire file and writing out the entire file, counting lines. ---- [RS]: Here is a case where [awk] is simpler than if we do it in [Tcl]. Say, you want all but the 4th line: gawk 'NR!=4' infile > outfile [sed] is also a candidate: sed -n -e "4!p" infile > outfile [[Anyone know a more concise ('''-n'''-less?) way to achieve the same?]] [AMG]: Here ya go: sed 4d infile > outfile You tried too hard. :^) This is even simpler than your [awk] version. Sed is a wonderful thing... too bad it's a write-only language. [http://sed.sourceforge.net/grabbag/scripts/dc.sed] [http://sed.sourceforge.net/grabbag/scripts/dc_overview.htm] To modify the original file rather than creating a new file, do either of the following: sed 4d infile > tmpfile && mv tmpfile infile sed -i 4d infile The latter only works with recent versions of [GNU] [sed], but it can be quite handy, especially when dealing with multiple files. It internally uses temporary files, which is a good thing as I note below. ---- [AMG]: The last time someone asked this question in the [Tcl'ers Chat], I wrote a sample program to do the job. I'd post it here but I didn't keep it... I guess I could write it a second time. Or I'll spell it out and let someone else translate to Tcl. Anyway, my first thought was: 1. [[[open]]] the file for reading and writing, 2. Search for the line to delete using [[[gets]]] and [[[string equal]]], [[[regexp]]], etc., 3. Use [[[tell]]] to find the file position at the end of the matching line, 4. [[[read]]] to the end of the file, 5. [[[seek]]] back to the saved position, 6. [[[puts] -nonewline]] the buffered data from the [[[read]]], and 7. Truncate the file. But at the time there was no way to truncate files, so I had to apologize for Tcl's inadequacy and change my approach: 1. [[[open]]] the file for reading, 2. Search for the line to delete, 3. [[[append]]] each ''non-matching'' line to a buffer, 4. Following a hit, [[[read]]] to the end of the file, and append this data to the buffer, 5. [[[close]]] the file, 6. Re-[[[open]]] the file for writing (using truncate mode "w"), and 7. [[[puts] -nonewline]] the buffered data. I don't like this version so much because it uses a larger buffer and overall it seems more fragile. But if multiple lines are to be deleted, or if more complicated transforms are called for, it may be more desirable. But now there's a [[[chan truncate]]] command, so the first approach is viable! Yay. '''IMPORTANT:''' Both approaches are fragile due to possible races with other processes accessing the same file. Between the start of step (6) and step (7), the file's contents are "incorrect" and will be either contain junk at the end or will be too short, in the case of the first and second approach, respectively. With approach #1, if '''C''' is to be deleted from '''ABCDEFG''', the file will momentarily contain '''ABDEFGG''' before being truncated to '''ABDEFG'''. With approach #2, the file will be empty, contain '''A''', '''AB''', '''ABD''', etc. before finally coming to rest at '''ABDEFG'''. To fix this fragility, don't try to overwrite the file in place. Instead write to a temporary file. If all is well, atomically rename the new file on top of the original. This way the contents of the original file will be consistent at all times. The file's contents will atomically change from '''ABCDEFG''' to '''ABDEFG'''. All of the above [sed] examples work this way, more or less. ---- [LV] How does one ''atomically rename'' the new file on top of the original in Tcl? ---- [LV] I suppose it is too much to expect that one could somehow make use of exclusive opens cross-platform, isn't it? The page, "[How do I manage lock files in a cross platform manner in Tcl]" certainly illustrates that, whatever else, the answer isn't simple. ---- [[ [Category Example] | [Category File] ]]