Remove empty last line from string (output from pipe) - python

I like to remove the empty line after my output:
#!/usr/bin/python
os.system("find /home/pi/bsp/musik/musik/ -name ""*.mp3"" | shuf -n 1 > /home/pi/bsp/musik/musik/track")
I get:
>>>cat track
/home/pi/bsp/musik/musik/2/Little Green Bag - George Baker Selection - Reservoir Dogs.mp3
But when I print the file in Python it's a different story:
>>>sudo python play.py
/home/pi/bsp/musik/musik/2/Lilly Allen - Fuck You.mp3
>>>>
...with a extra line in the end.
I like to pass a track to OMXPlayer, but with the additional line at the end there is no way...so I thought it canĀ“t be to hard to get rid of it:
I tried to save a to a new file and remove the empty line with:
os.system("sed '/^$/d' /home/pi/bsp/musik/track > /home/pi/bsp/musik/tt")
os.system("mv /home/pi/bsp/musik/tt /home/pi/bsp/musik/track ")
Or remove it right in the pipe with:
sed '/^$/d'
Or remove it from the sting with:
text = os.linesep.join([s for s in text.splitlines() if s])
Or:
track[:track.rfind('\n')]
And after all nothing worked so far.
How can I do it?

Assuming play.py is printing the contents of the file, the extra line at the end is coming from the print statement. If you need to output the contents of the file with Python, you can use sys.stdout.write instead of print, or rstrip('\n') the string, or put a comma at the end of the print statement, or use the print function with end=''. If you're directing input to OMXPlayer with shell redirection or something like that, it'll probably work fine without any extra effort.
import sys
sys.stdout.write(file_contents)
or
print file_contents.rstrip('\n')
or
print file_contents,
or
from __future__ import print_function
print(file_contents, end='')

text = track.rstrip()
"Return a copy of the string with trailing characters removed. If
chars is omitted or None, whitespace characters are removed."

Related

how to add header text with adjacent content in un-formatted data set, side by side with a delimiter separated value using sed/awk/python

I have a long list of unformatted data say data.txt where each set is started with a header and ends with a blank line, like:
TypeA/Price:20$
alexmob
moblexto
unkntom
TypeB/Price:25$
moblexto2
unkntom0
alexmob3
poptop9
tyloret
TypeC/Price:30$
rtyuoper0
kunlohpe6
mobryhox
Now, i want to add the header of each set with it's content side by side with comma separated. Like:
alexmob,TypeA/Price:20$
moblexto,TypeA/Price:20$
unkntom,TypeA/Price:20$
moblexto2,TypeB/Price:25$
unkntom0,TypeB/Price:25$
alexmob3,TypeB/Price:25$
poptop9,TypeB/Price:25$
tyloret,TypeB/Price:25$
rtyuoper0,TypeC/Price:30$
kunlohpe6,TypeC/Price:30$
mobryhox,TypeC/Price:30$
so that whenever i will grep with one keyword, relevant content along with the header comes together. Like:
$grep mob data.txt
alexmob,TypeA/Price:20$
moblexto,TypeA/Price:20$
moblexto2,TypeB/Price:25$
alexmob3,TypeB/Price:25$
mobryhox,TypeC/Price:30$
I am newbie on bash scripting as well as python and recently started learning these, so would really appreciate any simple bash scipting (using sed/awk) or python scripting.
Using sed
$ sed '/Type/{h;d;};/[a-z]/{G;s/\n/,/}' input_file
alexmob,TypeA/Price:20$
moblexto,TypeA/Price:20$
unkntom,TypeA/Price:20$
moblexto2,TypeB/Price:25$
unkntom0,TypeB/Price:25$
alexmob3,TypeB/Price:25$
poptop9,TypeB/Price:25$
tyloret,TypeB/Price:25$
rtyuoper0,TypeC/Price:30$
kunlohpe6,TypeC/Price:30$
mobryhox,TypeC/Price:30$
Match lines containing Type, hold it in memory and delete it.
Match lines with alphabetic characters, append G the contents of the hold space. Finally, sub new line for a comma.
I would use GNU AWK for this task following way, let file.txt content be
TypeA/Price:20$
alexmob
moblexto
unkntom
TypeB/Price:25$
moblexto2
unkntom0
alexmob3
poptop9
tyloret
TypeC/Price:30$
rtyuoper0
kunlohpe6
mobryhox
then
awk '/^Type/{header=$0;next}{print /./?$0 ";" header:$0}' file.txt
output
alexmob;TypeA/Price:20$
moblexto;TypeA/Price:20$
unkntom;TypeA/Price:20$
moblexto2;TypeB/Price:25$
unkntom0;TypeB/Price:25$
alexmob3;TypeB/Price:25$
poptop9;TypeB/Price:25$
tyloret;TypeB/Price:25$
rtyuoper0;TypeC/Price:30$
kunlohpe6;TypeC/Price:30$
mobryhox;TypeC/Price:30$
Explanation: If line starts with (^) Type set header value to that line ($0) and go to next line. For every line print if it does contain at least one character (/./) line ($0) concatenated with ; and header, otherwise print line ($0) as is.
(tested in GNU Awk 5.0.1)
Using any awk in any shell on every Unix box regardless of which characters are in your data:
$ awk -v RS= -F'\n' -v OFS=',' '{for (i=2;i<=NF;i++) print $i, $1; print ""}' file
alexmob,TypeA/Price:20$
moblexto,TypeA/Price:20$
unkntom,TypeA/Price:20$
moblexto2,TypeB/Price:25$
unkntom0,TypeB/Price:25$
alexmob3,TypeB/Price:25$
poptop9,TypeB/Price:25$
tyloret,TypeB/Price:25$
rtyuoper0,TypeC/Price:30$
kunlohpe6,TypeC/Price:30$
mobryhox,TypeC/Price:30$

How to enter a long and not-a-string data into the argument?

I have a problem with Python and need your help.
Take a look at this code:
import os
os.chdir('''C:\\Users\\Admin\\Desktop\\Automate_the_Boring_Stuff_onlimematerials_v.2\\automate_online-materials\\example.xlsx''')
The os.chdir() did not work because the directory I put in between the ''' and ''' is considered as raw string. Note that a line is no more than 125 characters, so I have to make a new line.
So how can I fix this?
You can split your statement into multiple lines by using the backslash \ to indicate that a statement is continued on the new line.
message = 'This message will not generate an error because \
it was split by using the backslash on your \
keyboard'
print(message)
Output
This message will not generate an error because it was split by using the backslash on your keyboard
Lines can be longer than 125 characters, but you should probably avoid that. You have a few solutions:
x = ('hi'
'there')
# x is now the string "hithere"
os.chdir('hi'
'there') # does a similar thing (os.chdir('hithere'))
You could also set up a variable:
root_path = "C:\\Users\\Admin\\Desktop"
filepath = "other\\directories" # why not just rename it though
os.chdir(os.path.join(root_path, filepath))
Do these work for you?
I'm also curious why you have to chdir there; if it's possible, you should just run the python script from that directory.

Pyperclip not pasting new lines?

I'm trying to make a simple script which takes a list of names off the clipboard formatted as "Last, First", then pastes them back as "First Last". I'm using Python 3 and Pyperclip.
Here is the code:
import pyperclip
text = pyperclip.paste()
lines = text.split('\n')
for i in range(len(lines)):
last, first = lines[i].split(', ')
lines[i] = first + " " + last
text = '\n'.join(lines)
pyperclip.copy(text)
When I copy this to the clipboard:
Carter, Bob
Goodall, Jane
Then run the script, it produces: Bob CarterJane Goodall with the names just glued together and no new line. I'm not sure what's screwy.
Thanks for your help.
Apparently I need to use '\r\n' instead of just '\n'. I don't know exactly why this is but I found that answer on the internet and it worked.
To include newlines in your file, you need to explicitly pass them to the file methods.
On Unix platforms, strings passed into .write should end with \n. Likewise, each of
the strings in the sequence that is passed into to .writelines should end in \n. On
Windows, the newline string is \r\n.
To program in a cross platform manner, the linesep string found in the os module
defines the correct newline string for the platform:
>>> import os
>>> os.linesep # Unix platform
'\n'
Souce: Illustrated Guide to Python 3

Modify string in bash to contain new line character?

I am using a bash script to call google-api's upload_video.py (https://developers.google.com/youtube/v3/guides/uploading_a_video )
I have a mp4 called output.mp4 which I would like to upload.
The problem is I cannot get my array to work how I would like.
This new line character is "required" because my arguments to python script contain spaces.
Here is a simplified version of my bash script:
# Operator may change these
hold=100
location="Foo, Montana "
declare -a file_array=("unique_ID_0" "unique_ID_1")
upload_file=upload_file.txt
upload_movie=output.mp4
# Hit enter at end b/c \n not recognized
upload_title=$location' - '${file_array[0]}' - Hold '$hold' Sweeps
'
upload_description='The spectrum recording was made in at '$location'.
'
# Overwrite with 1st call > else apppend >>
echo "$upload_title" > $upload_file
echo "$upload_description" >> $upload_file
# Load each line of text file into array
IFS=$'\n'
cmd_google=$(<$upload_file)
unset IFS
nn=1
for i in "${cmd_google[#]}"
do
echo "$i"
# Delete last character: \n
#i=${i[-nn]%?}
#i=${i: : -nn}
#i=${i::${#i}-nn}
i=${i%?}
#i=${i#"\n"}
#i=${i%"\n"}
echo "$i"
done
python upload_video.py --file=$upload_movie --title="${cmd_google[0]}" --description="${cmd_google[1]}"
At first I attempted to remove the new line character, but it appears that the enter or \n is not working how I would like, each line is not separate. It writes the title and description as one line.
How do I modify my bash script to recognize a newline character?
This is much simpler than you are making it.
# Operator may change these
hold=100
location="Foo, Montana"
declare -a file_array=("unique_ID_0" "unique_ID_1")
upload_file=upload_file.txt
upload_movie=output.mp4
upload_title="$location - ${file_array[0]} - Hold $hold Sweeps"
upload_description="The spectrum recording was made in at $location."
cat <<EOF > "$upload_file"
$upload_title
$upload_description
EOF
# ...
readarray -t cmd_google < "$upload_file"
python upload_video.py --file="$upload_movie" --title="${cmd_google[0]}" --description="${cmd_google[1]}"
I suspect the readarray command is all you are really looking for, since much of the above code is simply creating a file that I assume you are receiving already created.
I figured it out with help from chepner's answer. My question hid the fact that I wanted to write new line characters into the video's description.
Instead of adding a new line character in the bash script, it is much easier to have a text file which contains the correctly formatted script and read it in, then concatenate it with run-time specific variable.
In my case the correctly formatted text is called description.txt:
Here is a snip of my description.txt which contains newline characters
Here is my final version of the script:
# Operator may change these
hold=100
location="Foo, Montana"
declare -a file_array=("unique_ID_0" "unique_ID_1")
upload_title="$location - ${file_array[0]} - Hold $hold Sweeps"
upload_description="The spectrum recording was made in at $location. "
# Read in script which contains newline
temp=$(<description.txt)
# Concatenate them
upload_description="$upload_description$temp"
upload_movie=output.mp4
python upload_video.py --file="$upload_movie" --title="$upload_title" --description="$upload_description"

Python printing character-by-character in OSX Terminal

I'm trying to have Python copy the contents of a .txt file into the bash terminal on OS X (10.10), but the line does not print until every single character of the line has been printed to the line. Is there any way to have Python print each line character-by-character, instead of line-by-line? My code is designed to wait between characters, but each line simply takes a long time to print:
while True:
character = text_file.read(1)
if not character: break
else:
sys.stdout.write(character)
time.sleep(0.050)
When I run this code in IDLE, the characters print one at a time. In Terminal, lines take several seconds to print, and each line prints all at once. Is there any way to reproduce the behavior I'm seeing in IDLE in Terminal?
Add sys.stdout.flush() after sys.stdout.write(character)
The reason should be that the output of stdout is buffered.
if you want remove new line at the end of the line.
you can simply
print character,
will remove the new line(\n).

Categories

Resources