LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-26-2019, 10:45 PM   #1
anon033
Member
 
Registered: Mar 2019
Posts: 188

Rep: Reputation: 13
Display Items, but select original


The title is terrible, but essentially sums up what I need to do. I have a script that does the following:

Code:
cds into the home directory

finds all the videos in the vids directory

sorts them into order

removes the pathway and makes them more orderly

pipes them into dmenu for selection

passes the selected item to mpv
the UNIX shell script used is as follows:

Code:
cd ${HOME} && find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \) | sort | sed 's/.*\///' | pmenu -l 5 | xargs -I {} mpv "{}"
Now this works, sorta. This does display the output how I want, but once I select a video and it gets passed to mpv it can't play the video as the video doesn't exist. This is due to the fact that when the sed command gets run it changes the name of the file that mpv will try to play. I really want to change the name shown as it looks so much better and makes it easier to read, but how do I get mpv to play the original video?

Some sample output would be this:

Code:
#This is the vinilla output without using sed to parse output:

vids/Movies/Blade Runner 2049.mp4
vids/Movies/Blade Runner.mp4
vids/Movies/Ghost in the Shell (2017).mp4
vids/Movies/The God Who Wasnt There.mp4
vids/TV/Attack on Titan/S01E01 To You, Two Thousand Years Later.mkv
vids/TV/Attack on Titan/S01E02 That Day.mkv
vids/TV/Attack on Titan/S01E03 A Dull Light in Despair.mkv
vids/TV/Attack on Titan/S01E04 Night of the Disbanding.mkv
vids/TV/Attack on Titan/S01E05 First Battle.mkv
vids/TV/Attack on Titan/S01E06 The World She Saw.mkv
vids/TV/Attack on Titan/S01E07 A Small Blade.mkv
vids/TV/Attack on Titan/S01E08 I Can Hear a Heartbeat.mkv
vids/TV/Attack on Titan/S01E09 The Whereabouts of His Left Arm.mkv
vids/TV/Attack on Titan/S01E10 Answer.mkv
vids/TV/Attack on Titan/S01E11 Idol.mkv
vids/TV/Attack on Titan/S01E12 WOUND.mkv
vids/TV/Attack on Titan/S01E13 Basic Needs.mkv
vids/TV/Attack on Titan/S01E14 Can't Look into His Eyes.mkv
vids/TV/Attack on Titan/S01E15 Special Ops Squad.mkv
vids/TV/Attack on Titan/S01E16 What Should Be Done.mkv
vids/TV/Attack on Titan/S01E17 Female Titan.mkv
vids/TV/Attack on Titan/S01E18 Forest of Giant Trees.mkv
vids/TV/Attack on Titan/S01E19 Bite.mkv
vids/TV/Attack on Titan/S01E20 Erwin Smith.mkv
vids/TV/Attack on Titan/S01E21 Crushing Blow.mkv
vids/TV/Attack on Titan/S01E22 The Defeated.mkv
vids/TV/Attack on Titan/S01E23 Smile.mkv
vids/TV/Attack on Titan/S01E24 Mercy.mkv
vids/TV/Attack on Titan/S01E25 Wall.mkv
vids/TV/Death Note/S01EP01 Rebirth.mkv
vids/TV/Death Note/S01EP02 Confrontation.mkv
vids/TV/Death Note/S01EP03 Dealings.mkv
vids/TV/Death Note/S01EP04 Pursuit.mkv
vids/TV/Death Note/S01EP05 Tactics.mkv
vids/TV/Death Note/S01EP06 Unraveling.mkv
vids/TV/Death Note/S01EP07 Overcast.mkv
vids/TV/Death Note/S01EP08 Glare.mkv
vids/TV/Death Note/S01EP09 Encounter.mkv
vids/TV/Death Note/S01EP10 Doubt.mkv
vids/TV/Death Note/S01EP11 Assault.mkv
vids/TV/Death Note/S01EP12 Love.mkv
vids/TV/Death Note/S01EP13 Confession.mkv
vids/TV/Death Note/S01EP14 Friend.mkv
vids/TV/Death Note/S01EP15 Wager.mkv
vids/TV/Death Note/S01EP16 Decision.mkv
vids/TV/Death Note/S01EP17 Execution.mkv
vids/TV/Death Note/S01EP18 Ally.mkv
vids/TV/Death Note/S01EP19 Matsuda.mkv
vids/TV/Death Note/S01EP20 Makeshift.mkv
vids/TV/Death Note/S01EP21 Performance.mkv
vids/TV/Death Note/S01EP22 Guidance.mkv
vids/TV/Death Note/S01EP23 Frenzy.mkv
vids/TV/Death Note/S01EP24 Revival.mkv
vids/TV/Death Note/S01EP25 Silence.mkv
vids/TV/Death Note/S01EP26 Renewal.mkv
vids/TV/Death Note/S01EP27 Abduction.mkv
vids/TV/Death Note/S01EP28 Impatience.mkv
vids/TV/Death Note/S01EP29 Father.mkv
vids/TV/Death Note/S01EP30 Justice.mkv
vids/TV/Death Note/S01EP31 Transfer.mkv
vids/TV/Death Note/S01EP32 Selection.mkv
vids/TV/Death Note/S01EP33 Scorn.mkv
vids/TV/Death Note/S01EP34 Vigilance.mkv
vids/TV/Death Note/S01EP35 Malice.mkv
vids/TV/Death Note/S01EP36 1.28.mkv
vids/TV/Death Note/S01EP37 New World.mkv


# and with the parsing:

Blade Runner 2049.mp4
Blade Runner.mp4
Ghost in the Shell (2017).mp4
The God Who Wasnt There.mp4
S01E01 To You, Two Thousand Years Later.mkv
S01E02 That Day.mkv
S01E03 A Dull Light in Despair.mkv
S01E04 Night of the Disbanding.mkv
S01E05 First Battle.mkv
S01E06 The World She Saw.mkv
S01E07 A Small Blade.mkv
S01E08 I Can Hear a Heartbeat.mkv
S01E09 The Whereabouts of His Left Arm.mkv
S01E10 Answer.mkv
S01E11 Idol.mkv
S01E12 WOUND.mkv
S01E13 Basic Needs.mkv
S01E14 Can't Look into His Eyes.mkv
S01E15 Special Ops Squad.mkv
S01E16 What Should Be Done.mkv
S01E17 Female Titan.mkv
S01E18 Forest of Giant Trees.mkv
S01E19 Bite.mkv
S01E20 Erwin Smith.mkv
S01E21 Crushing Blow.mkv
S01E22 The Defeated.mkv
S01E23 Smile.mkv
S01E24 Mercy.mkv
S01E25 Wall.mkv
S01EP01 Rebirth.mkv
S01EP02 Confrontation.mkv
S01EP03 Dealings.mkv
S01EP04 Pursuit.mkv
S01EP05 Tactics.mkv
S01EP06 Unraveling.mkv
S01EP07 Overcast.mkv
S01EP08 Glare.mkv
S01EP09 Encounter.mkv
S01EP10 Doubt.mkv
S01EP11 Assault.mkv
S01EP12 Love.mkv
S01EP13 Confession.mkv
S01EP14 Friend.mkv
S01EP15 Wager.mkv
S01EP16 Decision.mkv
S01EP17 Execution.mkv
S01EP18 Ally.mkv
S01EP19 Matsuda.mkv
S01EP20 Makeshift.mkv
S01EP21 Performance.mkv
S01EP22 Guidance.mkv
S01EP23 Frenzy.mkv
S01EP24 Revival.mkv
S01EP25 Silence.mkv
S01EP26 Renewal.mkv
S01EP27 Abduction.mkv
S01EP28 Impatience.mkv
S01EP29 Father.mkv
S01EP30 Justice.mkv
S01EP31 Transfer.mkv
S01EP32 Selection.mkv
S01EP33 Scorn.mkv
S01EP34 Vigilance.mkv
S01EP35 Malice.mkv
S01EP36 1.28.mkv
S01EP37 New World.mkv
The fix:

Code:
#!/bin/sh
chosen=$(cd ${HOME} && find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \) | sort | sed 's|.*/||' | pmenu -l 5)

cd ${HOME} && find vids -name "*$chosen" -exec mpv \{} \;

Last edited by anon033; 06-27-2019 at 12:45 PM.
 
Old 06-27-2019, 01:42 AM   #2
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
You can't do it like that with either pmenu or dmenu I think - they simply spit back out what you chose.
This would require some proper scripting, possibly with bash arrays, not a oneliner.
Have you tried simply using bash's tab completion feature on the command line?
Code:
mpv vids<Tab><Tab>etc.
Or a command line filemanager like nnn?
 
Old 06-27-2019, 06:55 AM   #3
wadapad
LQ Newbie
 
Registered: Jun 2019
Posts: 1

Rep: Reputation: Disabled
between pmenu and xargs, add another find with '-name $(cat)', so find will give xargs file with full path
or replace last xargs with 'find vids -name "$(cat)" -exec mpv "{}" \;'

Last edited by wadapad; 06-27-2019 at 07:04 AM.
 
Old 06-27-2019, 11:26 AM   #4
anon033
Member
 
Registered: Mar 2019
Posts: 188

Original Poster
Rep: Reputation: 13
Quote:
Originally Posted by wadapad View Post
between pmenu and xargs, add another find with '-name $(cat)', so find will give xargs file with full path
or replace last xargs with 'find vids -name "$(cat)" -exec mpv "{}" \;'
I am very sorry, but could you give me a more detialed example? I am still learning the ins and outs of UNIX shell script and feel a little confused. To help myself with this I am breaking up the script like so

Code:
#!/bin/sh
cd ${HOME}

# find all videos
files=$(find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \))

# make titles easier to read
sorted=$("$files" | sort | sed 's/.*\///')

# select video to watch
chosen=$("$sorted" | pmenu -l 5 | xargs -I {} mpv "{}")
if I understand you correctly I am supposed to run:

Code:
find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \)
between

Code:
pmenu -l 5 |

# and 

xargs -I {} mpv "{}"
 
Old 06-27-2019, 11:59 AM   #5
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
If you don't mind using a fuzzy-finder like fzy or fzf, you could probably do that in a couple of lines.
Code:
#!/bin/sh

listings="$(find vids -type f -print)"

mpv "$(echo -n "$listings" | fzy -q "$(echo -n "$listings" | sed 's|.*/||' | fzy)")"

Last edited by individual; 06-27-2019 at 12:00 PM. Reason: Provided a more accurate example using mpv.
 
Old 06-27-2019, 12:29 PM   #6
anon033
Member
 
Registered: Mar 2019
Posts: 188

Original Poster
Rep: Reputation: 13
Quote:
Originally Posted by individual View Post
If you don't mind using a fuzzy-finder like fzy or fzf, you could probably do that in a couple of lines.
Code:
#!/bin/sh

listings="$(find vids -type f -print)"

mpv "$(echo -n "$listings" | fzy -q "$(echo -n "$listings" | sed 's|.*/||' | fzy)")"
Thank you, I'll keep this in my backpocket; but I want to do my best to do this with the tools I have at the moment.
 
Old 06-27-2019, 12:39 PM   #7
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by FOSSilized_Daemon View Post
Thank you, I'll keep this in my backpocket; but I want to do my best to do this with the tools I have at the moment.
Is it because you want to learn how "core utilities" work? Or is it because of "bloat?" There is a difference. Anyway, here is a POSIX-compliant version of the above, without the easy selection.
Code:
#!/bin/sh

cd "$HOME" || exit

find vids -type f -print | sed 's|.*/||'
read -p '> ' -r chosen
find vids -name "*$chosen" -exec mpv \{} \;
 
1 members found this post helpful.
Old 06-27-2019, 12:44 PM   #8
anon033
Member
 
Registered: Mar 2019
Posts: 188

Original Poster
Rep: Reputation: 13
Talking

Quote:
Originally Posted by individual View Post
Is it because you want to learn how "core utilities" work? Or is it because of "bloat?" There is a difference. Anyway, here is a POSIX-compliant version of the above, without the easy selection.
Code:
#!/bin/sh

cd "$HOME" || exit

find vids -type f -print | sed 's|.*/||'
read -p '> ' -r chosen
find vids -name "*$chosen" -exec mpv \{} \;
Thank you so much! This worked!

Code:
#!/bin/sh
chosen=$(cd ${HOME} && find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \) | sort | sed 's|.*/||' | pmenu -l 5)

cd ${HOME} && find vids -name "*$chosen" -exec mpv \{} \;
 
Old 06-27-2019, 12:45 PM   #9
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by FOSSilized_Daemon View Post
Thank you so much! This worked!

Code:
#!/bin/sh
chosen=$(cd ${HOME} && find vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \) | sort | sed 's|.*/||' | pmenu -l 5)

cd ${HOME} && find vids -name "*$chosen" -exec mpv \{} \;
You're welcome. You can also do "*$chosen*" so you don't need to type the full name. I forgot to include that in my post.

Example:
Code:
Blade Runner 2049.mp4
Blade Runner.mp4
S01EP36 1.28.mkv
S01EP37 New World.mkv
S01EP35 Malice.mkv
> 1.28
Playing: vids/TV/Death Note/S01EP36 1.28.mkv
EDIT: Don't duplicate the work by cd'ing into $HOME twice. Just do it once at the beginning of your script.

Last edited by individual; 06-27-2019 at 12:47 PM.
 
1 members found this post helpful.
Old 06-27-2019, 01:05 PM   #10
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by individual View Post
Code:
#!/bin/sh

cd "$HOME" || exit

find vids -type f -print | sed 's|.*/||'
read -p '> ' -r chosen
find vids -name "*$chosen" -exec mpv \{} \;
IDK, I find this very... inelegant. and error perone, too: what if 2 videos are in different folders, but have the same name? And mpv does not seem to take a list of files by default.

Not that I could think of a better solution; the whole premise is faulty IMO.
 
Old 06-27-2019, 01:12 PM   #11
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by ondoho View Post
IDK, I find this very... inelegant. and error perone, too: what if 2 videos are in different folders, but have the same name? And mpv does not seem to take a list of files by default.

Not that I could think of a better solution; the whole premise is faulty IMO.
Normally I would agree, but that wasn't the purpose of my post. It provided a starting point for the OP, and if he wants to expand, then more power to him. The directory/file structure is quite specific in this case so the likelihood of duplicate show/movie titles is low.
 
Old 06-27-2019, 02:12 PM   #12
anon033
Member
 
Registered: Mar 2019
Posts: 188

Original Poster
Rep: Reputation: 13
I actually have one other thing I am trying to figure out if you have a moment, this is something I will actually be implementing in several scripts. As you know this script will find all videos in the vids directory. The way I order my directories is:

Code:
vids/TV/"show names"/"seasons if any is available"
vids/Movies/"name of movies"
Now the thing I want to add is that I want the output (IE when I select my video) to show sections, like show all tv shows under "TV/show name/season if any is there" and movies as "Movies/moviename". A better way to display this would be with an example, so a better visual would be this:

Code:
TV:

Death Note:

Season one:

S01EP01 Rebirth.mkv

ETC

Movies:

Blade Runner 2049.mp4
Blade Runner.mp4
ETC
I have no idea how to do this, what would be the best way to do this? I want to get this working here as I plan to use it in a similar script for music. Just for clarification this would mean that the show for example is stored under ~/vids/Death Note/Season One/EP Name

Last edited by anon033; 06-27-2019 at 02:17 PM.
 
Old 06-28-2019, 01:59 AM   #13
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
So basically you want to split paths along '/' characters?
bash has some nice tools for that, specifically string manipulation:
https://mywiki.wooledge.org/BashFAQ/100 (you really want to read ALL of the BashFAQ)
Example:
Code:
#!/bin/bash

path="/home/ondoho/video/CSI Crime Scene Investigation/CSI - 3x23 - Inside The Box.avi"
lastbit="${path##*/}"
echo "$lastbit"
beforelast="${path%/$lastbit}"
beforelast="${beforelast##*/}"
echo "$beforelast"
# etc...
 
Old 06-28-2019, 02:50 AM   #14
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
I'm not sure I completely understood your question. You want to print out all files that are in the same directory as the selected one? If that's what you want you can add a few lines to what you already have.
Code:
# list all files in the vids directory and allow a user to choose one.
mediaFile="$(find vids -type f -print | sed 's|.*/||' | sort | pmenu -l 5)"

# find the directory that the chosen file resides in.
mediaDir="$(find vids -iname "*$mediaFile*" -exec dirname \{} \; -quit)"

# remove vids/ from the front of the directory name; replace / with a newline; replace the end of each resulting string with ':.'
echo "$mediaDir" | cut -d'/' -f2- | tr '/' '\n' | sed 's|$|:|'

# list the contents of the directory.
ls -1 "$mediaDir"

# start mpv with $mediaFile here?
And the result:
Code:
TV:
Death Note:
Season One:
S01EP01 Rebirth.mkv
S01EP02 Confrontation.mkv
EDIT: I learned something new as well. You can stop find after the first match by using -quit.

Last edited by individual; 06-28-2019 at 03:20 AM. Reason: Typo
 
Old 06-28-2019, 11:43 AM   #15
anon033
Member
 
Registered: Mar 2019
Posts: 188

Original Poster
Rep: Reputation: 13
I am gonna rewrite this to make it easier to read (sorry about the last one, it was poorly formatted). What I am trying to do in this script is the following:

Code:
1) Find all videos in ~/vids/ (this is done using: find ${HOME}/vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \))

2) Find the directories the files are listed in under ~/vids/ (IE: TV/showname/season or Movies/Moviename etc) I don't know how to do this part

3) Ask the user which video they want to watch via dmenu (which would look like this):

TV:

Death Note:

Season one:

S01EP01 Rebirth.mkv

ETC

Movies:

Blade Runner 2049.mp4
Blade Runner.mp4
ETC

4) Play the video the user selected

5) If the user doesn't select a video (IE $file = nothingor they use escape which closes dmenu) exit
Right now I have this version:

Code:
#!/bin/sh
chosen=$(find ${HOME}/vids/ -type f \( -name "*.mp4" -o -name "*.mkv" \) | sort | sed 's|.*/||' | pmenu -l 5)

find ${HOME}/vids/ -name "*$chosen" -exec mpv \{} \;
As you know this version asks the user which video to watch and then plays it. I can't figure out how I would get this to work the other way.

Last edited by anon033; 06-28-2019 at 01:14 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Customization of the number of items to display in LQ Spy view l0f4r0 LQ Suggestions & Feedback 9 08-28-2018 11:18 AM
Display the list of items on webpage, that have not been updated in the last 3 days using msql sathishncd Programming 16 12-16-2017 08:04 AM
[SOLVED] Select / For and testing how many items in list grail Programming 4 08-08-2014 10:32 AM
[SOLVED] bash select items not in array eamesj Programming 12 01-03-2013 05:11 PM
Select() did not select my socket thvo Programming 1 05-08-2005 12:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:06 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration