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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
|
02-20-2013, 01:52 PM
|
#1
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Rep:
|
Filenames with spaces in bash scripts.
Code:
#list.sh
#!/bin/sh
list="$(ls *mp3)"
n=0
for file in $list
do
v[n]="$file"
let n=n+1
done
n=0
until [ -z "$1" ]
do
echo "${v[$1]}"
shift
let n=n+1
done
exit
This script takes an argument n and prints the name of the n+1 th file in the current directory. If given several arguments, for example
it prints the 1st, 4th and 5th filename in the directory. The problem is that there may be spaces in the filenames. If the 1st file is "john smith", then 'list.sh 1' will not print the 2nd file name but "smith". The problem is in the first half of the script, the repeat block can be disregarded. How can I solve this?
|
|
|
|
02-20-2013, 02:26 PM
|
#3
|
|
Senior Member
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 1,656
|
Code:
list="$(ls *mp3)"
for file in $list
should be
|
|
|
|
02-20-2013, 02:27 PM
|
#4
|
|
Member
Registered: Nov 2007
Location: Seattle
Distribution: Debian Squeeze, Wheezy
Posts: 153
Rep:
|
One option may be to read the list of files directly into an array with one file per line:
Code:
IFS=$'\n'
list=($(ls -1 *.mp3))
# or use $(find ~/mp3folder/ -iname '*.mp3' -print) for a recursive search
IFS=''
n=0
for file in "${list[@]}"
do
echo "$file"
((n++))
done
Regards,
Stefan
|
|
|
|
02-20-2013, 02:56 PM
|
#5
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Original Poster
Rep:
|
Thank you very much. The links solved the problem. Could I ask you how to determine, within a bash script, if a certain string contains a given substring. For example, given "superior" I want to know it if contains "upe", which here is certainly true.
More precisely, the problem is this: one of the arguments can be of the form m-n, for example,
The program would have to know the last argument contains a hyphen (it means play from 6 up to 8) and get the 6 and the 8. Is this very difficult? Once the presence of the hyphen is detected, perhaps sed could extract m and n.
Last edited by stf92; 02-20-2013 at 02:58 PM.
|
|
|
|
02-20-2013, 03:24 PM
|
#6
|
|
Moderator
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.4 OpenSuSE 12.2
Posts: 9,896
|
You can try the pattern matching operator =~. In order to match a numeric interval, looking for an hyphen is not enough, otherwise strings like "-8" or "hello-world" or "6-" would be valid. Instead you have to match the numbers as well:
Code:
[[ $1 =~ ^[0-9]+-[0-9]+$ ]] && echo "$1 is a numeric interval"
|
|
|
1 members found this post helpful.
|
02-20-2013, 03:49 PM
|
#7
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Original Poster
Rep:
|
Cool! Then I could do
Code:
s1=$(echo $1|sed s/"-"/" ")
Having now a blank separator between the two numbers I guess it would be easy to put each one in a separate variable, though I do not immediately see how to do it.
|
|
|
|
02-20-2013, 10:05 PM
|
#8
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Original Poster
Rep:
|
I did it this way:
Code:
# play.sh
# Example: play.sh 0 3-5 8
# Play 1st, 4th, 5th, 6th and 9th files in current directory.
#!/bin/sh
n=0
for file in *mp3
do
v[n]="$file"
let n=n+1
done
n=0
until [ -z "$1" ]
do
if [[ $1 =~ ^[0-9]+-[0-9]+$ ]] # Thanks colucix
then
# $1 is an interval m-n
int=$1
# Split "m-n" in "m" and "n"
n1="${int%-*}" # Get m
n2="${int##*-}" # Get n
# Process from v[n1] up to v[n2]
for (( i=$n1; i <= $n2; i++ )); do
mplayer "${v[i]}"
done
else
mplayer "${v[$1]}"
fi
shift
let n=n+1
done
exit
It works.
|
|
|
|
02-21-2013, 02:36 AM
|
#9
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,316
|
Now you have a solution .. here is another way to think about
Code:
#!/bin/bash
files=( *.mp3 )
for f
do
if [[ $f =~ - ]]
then
for (( i = ${f%-*}; i < ${f#*-}; i++ ))
do
mplayer "${files[i]}"
done
f=${f#*-}
fi
mplayer "${files[f]}"
done
I would probably add in a test to make sure that the directory where you run this actually has mp3 files, ie test if array empty.
Many others of course ... just thought it might interest you.
Last edited by grail; 02-21-2013 at 02:37 AM.
|
|
|
|
02-21-2013, 03:42 AM
|
#10
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Original Poster
Rep:
|
I like it. It seems more compact.
|
|
|
|
02-21-2013, 03:58 AM
|
#11
|
|
Senior Member
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 2,487
Original Poster
Rep:
|
If I press ^C while the script is running it has no other effect than making mplayer go on to the next song. How could I stop the program in response to ^C or some other key?
|
|
|
|
02-21-2013, 08:32 AM
|
#12
|
|
Guru
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 6,316
|
Probably need to investigate the trap and / or wait command.
|
|
|
|
02-21-2013, 08:48 AM
|
#13
|
|
Member
Registered: Aug 2008
Distribution: Slackware
Posts: 178
Rep:
|
Quote:
Originally Posted by propofol
One option may be to read the list of files directly into an array with one file per line:
Code:
IFS=$'\n'
list=($(ls -1 *.mp3))
# or use $(find ~/mp3folder/ -iname '*.mp3' -print) for a recursive search
IFS=''
n=0
for file in "${list[@]}"
do
echo "$file"
((n++))
done
|
No. This is incorrect. File names can have new line characters in them.
Quote:
Originally Posted by stf92
More precisely, the problem is this: one of the arguments can be of the form m-n, for example,
|
Code:
foo=6-8
range=false
case $foo in
*-*-*)
echo "$foo: invalid argument" >&2
exit 1
;;
?*-?*)
foo1=${foo%-*}
foo2=${foo#*-}
;;
*-*)
echo "$foo: invalid argument" >&2
exit 1
esac
if $range; then
: use $foo1 and $foo2
else
: use $foo
fi
Last edited by mina86; 02-21-2013 at 08:54 AM.
|
|
|
|
02-22-2013, 01:06 AM
|
#14
|
|
Member
Registered: Nov 2007
Location: Seattle
Distribution: Debian Squeeze, Wheezy
Posts: 153
Rep:
|
Quote:
Originally Posted by mina86
No. This is incorrect. File names can have new line characters in them.
|
You are correct but how many files do you have on your system with '\n' in the name? If you want to be pedantic: find with '-print0' & IFS=$'\0'
|
|
|
|
02-22-2013, 08:54 AM
|
#15
|
|
Member
Registered: Aug 2008
Distribution: Slackware
Posts: 178
Rep:
|
Quote:
Originally Posted by propofol
You are correct but how many files do you have on your system with '\n' in the name?
|
Irrelevant. Assuming that files with new line characters do not exist is incorrect and may lead to security bugs.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 03:37 AM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|