How to remove all empty lines from beginning and end of file - python-3.x

I have a file that looks like
Blank Line
Blank Line
Blank Line
Blank Line
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Morbi a justo egestas, malesuada lacus ut, euismod purus.
Etiam faucibus felis ac orci varius cursus.
Praesent tincidunt nibh condimentum, finibus odio non, euismod tortor.
Quisque eget ligula eu turpis consequat rutrum.
Cras non ipsum vel ipsum sodales ullamcorper non vitae dui.
Blank Line
Blank Line
Blank Line
Blank Line
The Blank Line is literally blank line. I could not put blank lines in the beginning and end in the code block so using the text Blank Line.
I need to remove all the blank lines from the beginning and end of this file. Please notice that there are blank lines in between lines. I do not want to remove those.
I have come up with the following code that remove all blank lines from the beginning of the file. But I could not manage to remove all the blank lines at the end of the file.
#!/usr/bin/env python3
import sys
import argparse
import logging
parser = argparse.ArgumentParser()
parser.add_argument("infile", nargs="?", type=argparse.FileType("r"), default=sys.stdin)
parser.add_argument(
'-d',
'--debug',
help="Print lots of debugging statements",
action="store_const",
dest="loglevel",
const=logging.DEBUG,
default=logging.WARNING,
)
parser.add_argument(
'-v',
'--verbose',
help="Be verbose",
action="store_const",
dest="loglevel",
const=logging.INFO,
)
args = parser.parse_args()
if sys.stdin.isatty() and args.infile.name == "<stdin>":
sys.exit("Please give some input")
logging.basicConfig(level=args.loglevel)
# Business Logic Here
do_not_print_all_lines = True
for line in args.infile:
if not line.strip() and do_not_print_all_lines:
pass
else:
do_not_print_all_lines = False
if not do_not_print_all_lines:
print(line)
How can I do that?

Can you just first read the file into a list?
Then, you can address empty lines from the beginning and the end of the list

Something like this:
my_file = open("sample-file.txt", "r")
lines = my_file.readlines()
# inspection starting from beginning of list
for n in range(len(lines)):
line = lines[n].strip()
if line == "":
frm= n
else:
break
# inspection starting from end of list
for n in range(len(lines)-1,-1,-1):
line = lines[n].strip()
if line == "":
to= n
else:
break
newlines = lines[frm+1:to]
print(newlines)

Related

Can VIM do this Sublime trick?

I want to edit this text:
Aenean vel sem bibendum, eleifend odio a, dictum nibh.
The third word in the above line is
Morbi eget est vitae quam ultricies porta vitae quis nunc.
The third word in the above line is
Praesent accumsan ex a laoreet cursus.
The third word in the above line is
Quisque efficitur lectus at dolor mollis, sit amet tristique libero lobortis.
The third word in the above line is
to this text:
Aenean vel sem bibendum, eleifend odio a, dictum nibh.
The third word in the above line is sem
Morbi eget est vitae quam ultricies porta vitae quis nunc.
The third word in the above line is est
Praesent accumsan ex a laoreet cursus.
The third word in the above line is ex
Quisque efficitur lectus at dolor mollis, sit amet tristique libero lobortis.
The third word in the above line is lectus
To do this with Sublime
Select repeated part
ALT+F3
UpArrow
HOME
3 x CTRL+RightArrow
CTRL+Shift+LeftArrow
CTRL+C
DownArrow
END
CTRL+V
this trick is very useful in many cases.
can VIM do it?
It should work easily with a macro. If you have your cursor on the first character of the first line then:
qq: start recording macro named q
2w: advance two words
yw: yank (copy) word
j$: jump to next line and go to end of line
p: paste what you've yanked
+: go to start of next line
q: stop recording macro.
3#q: execute macro named q 3 times
As an alternative to a macro solution, you could also use a substitute command
:%s/\vis $\zs/\=split(getline(line('.')-1), ' ')[2]
breakdown
:%s/ start a substitute command
\vis $\zs/ select lines ending with "is "
use \zs to start replacing after the match
\=split(getline(line('.')-1), ' ')[2] split previous line on spaces and use the 3th item from the list
Note that to use this as a general template following has to hold
You need a search criteria to only match the lines you like to change. For your example, this is is $
You need to be able to split the previous line on something meaningfull returning the item you need in the same array position for each substituion. For you example this is by splitting on space and returning the 3th item.
Another vim solution:
:g/^/if line('.') % 2 | normal! wwyiwj$p | endif
g .................. globally
/^/ ................ on every start of line
if
line('.') % 2 ...... Mod of the integer division of line number by 2
normal! ............ normal mode
ww ................. jump to the third word
yiw ................ yank inner word (word under cursor)
j .................. go to the line below
$ .................. jump to othe end of the line
p .................. paste

Lua string operation

I'm trying to figure out a way, so far unsuccessfully, to add a new line ("\n") to a very long string.
Is there a function that will insert a new line every x amount of characters? Basically, I need to add a newline every 95 characters. Here's the text I'm working with:
MEMORANDUM FOR RECORD
SUBJECT: Subject
1) Nam fabulas mnesarchum comprehensam ne, cu ullum euismod consulatu usu. Eam alii lobortis
voluptatum id, denique eligendi pertinax quo ne. Vis congue eirmod ut. Duo probo soleat ex. Elit pertinax
abhorreant eu his, ipsum dicam dissentiunt pri id. Kasd erant dolorum id sed, ei vim partem deseruisse,
ne mea dico tantas alienum.
2) Has cu facilisis mediocritatem. Fabellas lucilius vim ex. Mei simul omnium et, wisi vidit ut ius.
Ad has erat honestatis. Malis animal aliquid id usu.
3) Nulla utinam appellantur cu qui, scripta sententiae disputando eu nam, ut pri unum labore.
Odio wisi torquatos sea cu. Ut detracto torquatos repudiandae pri. Vim puto solum epicurei at.
Per nonummy perpetua similique te, odio platonem ut pri. Mei indoctum prodesset in, eam nisl quaerendum at.
4) At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium
voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati
cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est
laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam
libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.
I'm interpreting the question as: I want to divide the text into lines of at most, but as close as possible to 95 characters, breaking on whitespace.
I'm ignoring the file IO in the other answers. Here goes:
-- Second parameter governs where to break; defaults to 80.
-- Call me like: breakAt(longstring, 95)
local function breakAt(str, lineLength)
local lineLength = lineLength or 80
-- Arrays are more efficient for large text operations.
local out = {}
-- Match line without newlines; save original newlines.
for line, breaks in str:gmatch('([^\n]+)(\n+)') do
local count = 0
-- Match whitespace with '*' to allow for the last word on the line having no adjacent whitespace.
for word, whitespace in line:gmatch('(%S+)(%s*)') do
count = count + #word
if count > lineLength then
-- If this word crosses the lineLength boundary, replace the last words' whitespace with a newline.
out[#out] = '\n'
-- The current word is the first on the new line.
count = #word
end
count = count + #whitespace
table.insert(out, word)
table.insert(out, whitespace)
end
table.insert(out, breaks)
end
return table.concat(out)
end
This'll break the string on the whitespace, maximizing the number of words on a line.
It's easy!
local text = io.open'memorandum.txt':read'*a' -- Load text from file
local n0, width = 0, 80
text = text:gsub('()(%s)',
function(n, c)
c = (n-n0 > width) and '\n' or c
n0 = (c == '\n') and n or n0
return c
end)
io.open('memorandum2.txt','w'):write(text) -- Save corrected text to file
Try print(s:gsub("("..string.rep(".",95)..")","%1\n")).
But I suspect you want to do this for each line, not for the whole text.
This will directly output any lines shorter than 95 characters, and split lines 95+ characters into 94 character chunks with a newline appended. it doesn't split on white-space, that is left as an exercise to you.
local fout = io.output(os.getenv('userprofile').. '\\desktop\\temp.txt', 'w+');
for str in string.gmatch(text, '(.-\n)') do
if str:len() > 95 then
while str:len() > 95 do
local s = str:sub(1, 94)
fout:write(s.. '\n')
str = str:sub(94)
end
else
fout:write(str)
end
end
fout:flush(); fout:close();

VIM: Insert a line number, with a space after

I need to insert the line number before each line of text using Vim, and there has to be a space after the line number. For example, if this was TestFile:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Morbi nunc enim, vehicula eget, ultricies vel, nonummy in, turpis.
It should look like this
1 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
2 Morbi nunc enim, vehicula eget, ultricies vel, nonummy in, turpis.
I have been using the command :%s/^/\line('.')/ with a number of variations, but I cannot figure out how to get the space at the end.
Any ideas?
You were very close!
This substitution will do the job by concatenating the string ' ' to the line number:
%s!^!\=line('.').' '!
This is probably easiest with an external tool:
:%!nl -ba -w1 -s' '
You can use a macro. First make sure you have a 0 before the first line and have your cursor placed on it:
0 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Morbi nunc enim, vehicula eget, ultricies vel, nonummy in, turpis.
foo
bar
etc...
Then perform this key sequence to store the right macro in register a: qaywjP0<C-A>q.
Now press #a to execute the macro. Use a quantifier to execute it multiple times.
Type :help q to find out more about recording macro's.

read and writing in tcl

Is there any way to read while it is writing at the same time in TCL?
I tried to use w + so and it didn't work.
set f0 [open out11.tr w+]
So I want to read every line that has been done writing at the same time
While the w+ mode will work, it does truncate the file when you open it (because it's a modification of the w mode which does the same thing). If you don't want to wipe the existing data, use r+ instead (in which case the file must exist first).
When you want to create the file if it doesn't exist, be able to read and write it through the same channel, and don't want to truncate it on open, you have to use the other form of mode descriptor (derived from POSIX descriptors, if you're interested in mnemonics):
set f0 [open out11.tr {RDWR CREAT}]
(w+ is RDWR CREAT TRUNC, r+ is plain RDWR.)
The following example opens a file with w+ (means read/write, but truncate the contents if file already exists). It then writes each line, and read back, write, then read back, ...
set lines {
{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi}
{accumsan est ut ante ornare et porta sem iaculis. Fusce a dolor}
{magna, eget viverra quam. In sem justo, hendrerit a porttitor sit}
{amet, scelerisque eu turpis. Nulla arcu arcu, condimentum vel}
{fermentum sit amet, vulputate et sapien. Aenean convallis, purus vel}
{molestie vehicula, diam eros adipiscing nibh, in dapibus nisi orci}
{ut nisl. Ut fermentum felis a lectus lacinia dapibus. Nunc cursus}
{nunc vitae massa fermentum imperdiet. In eu lectus quis arcu}
{convallis imperdiet in quis tortor.}
}
set f [open out.txt w+]
set lastRead 0
foreach line $lines {
# Write to the file
puts $f $line
# Read it back and display to stdout
seek $f $lastRead
gets $f line2
set lastRead [tell $f]
}
close $f

How to get a custom sentence format in VIM?

I use vim to write a lot of text (mostly for research papers), and I recently start to format paragraphs and sentences like this:
Lorem ipsum dolor sit amet, consectetur adipiscing
elit sed diam et arcu scelerisque rutrum eget
vitae sed diam et arcu scelerisque rutrum eget
vitae sed diam et arcu scelerisque rutrum eget
vitae.
Aenean euismod tristique sollicitudin.
Vestibulum sed diam et arcu scelerisque rutrum eget
vitae sapien.
Quisque dui ligula, semper eget iaculis at, eleifend
at ligula.
Sed vestibulum tellus ac libero iaculis sit amet commodo
sapien pellentesque.
Cras quis dignissim neque.
Donec neque mauris, dictum tempus tincidunt in,
pellentesque sit amet dui.
I hope you can guess the pattern.
Now I do this mostly manual what is some kind of akward, especially if you add text in the middle of the sentence. My question would be, how can i do this automagically?
I know that I can use "gq100" to force a linebreak on the next 100 lines, but this does not do exactly what I want. It would be great if this is not really a hard linebreak but only a virtual one, which means when I put the cursor in the line starting with "Lorem ipsum" I can copy and past the whole sentence with y and p as if there wouldn't be any linebreak at all.
Does someone have an idea on this one?
Cheers,
T
Do you mean: If a line starts with 3 spaces, it belong to previous sentence?
You can do this:
:set textwidth=0
:set wrap
:set showbreak=\ \ \
Note: there's a space after every \.
Try to type a very lone line. It'll auto wrap. And the next line starts with 3 spaces.
I guess this is what you are looking for, the breakindent patch for vim:
http://sqizit.bartletts.id.au/2011/01/31/vim-and-breakindent/

Resources