LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Script Help "Line Spliting" (https://www.linuxquestions.org/questions/linux-newbie-8/script-help-line-spliting-919339/)

jv2112 12-18-2011 11:01 AM

Script Help "Line Spliting"
 
I am trying to create a list of files in a group of directories and chop off the extensions. However when I try it splits into lines. I tried quoting the list "$(ls -R ~joe/Videos)" but then my line cutting off the extension does not work.

I feel like I should knwo what I am doing wrong but I can't seem to figure it out....:banghead:

Quote:

#! /bin/bash
clear
figlet Video List
for files in $(ls -R ~joe/Videos)
do
echo "${files%%.*}"
done


All Help is Appreciated !! :cool:

jschiwal 12-18-2011 11:21 AM

Using "${file%%.*}" will remove everything right of the first period. Not just the extension if a filename contains multiple periods.
Use "${file%.*}" instead.

Another problem may be due to white space in names. A filename with a space in it could be split into two arguments.
Here is a howto on different ways to deal with them using for and while loops:
http://www.cyberciti.biz/tips/handli...s-in-bash.html
So you could use
Code:

ls -- . | while read file; do echo "${file%.*}"; done
Sometimes, I will use find to construct lines of bash code, using the -printf find command. Then I can create a line of code and add quotes around the filename. This works well, over using -exec, if different forms of the filename are used more than once in the command.

Telengard 12-18-2011 11:27 AM

Quote:

Originally Posted by jschiwal (Post 4553018)
Sometimes, I will use find to construct lines of bash code, using the -printf find command. Then I can create a line of code and add quotes around the filename.

Neat idea! :cool:

wpeckham 12-18-2011 01:34 PM

Although...
 
While I prefer to do everything possible in BASH when scripting (or move it to PERL is I can avoid all exterior calls that way) I may have a useful suggestion. Have you checked the man pages for 'basename' and 'dirname'?
The 'basename' utility specifically allows you to remove KNOWN extensions, the trick being that you must specify the extension.
If the extensions you expect constitute a large or ill-defined range then you are in for an interesting amount of string manipulation, and will want to do things more efficiently than you could with basename.

Roughly how many files with how many different extensions might we be considering?

jv2112 12-18-2011 04:20 PM

Thanks for the education and suggestions. The while loop method listed works well. I have about 600 files with about 7-10 different extensions so fewer lines of code the better for this small intermittent task.

:cool: ----------Thanks again ----------------- :cool:


Quote:


#! /bin/bash
clear
figlet Collection List
echo -e "\e[00;34mWhat parent directory does your collection start ? \e[00m"
read start
echo
echo -e "\e[00;31m ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \e[00m"
echo
echo -e "\e[00;33m What do you want to call your list ? \e[00m"
read Collection
touch /home/$USER/"$Collection-$(date +%F)"
ls -R $start | while read file; do echo "${file%.*}" >>$Collection-$(date +%F); done
echo -e "\e[00;31m---- Preparing File : $Collection ---- \e[00m"

sleep 5
echo -e "\e[00;31m ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \e[00m"
echo -e "\e[44;37m Do you want to view \e[44;33m$Collection. \e[00;34m--Yes / No - \e[00m"
read ans
case $ans in
Yes | yes) less /home/$USER/"$Collection-$(date +%F)" ;;
* ) figlet Exiting ...
sleep 3
cowsay "Goodbye $USER"
;;
esac



grail 12-19-2011 04:19 AM

Well apart from not being a fan of using ls to parse data (for reasons outline here), something I found a little odd with your script is the following:
Code:

touch /home/$USER/"$Collection-$(date +%F)"
echo "${file%.*}" >>$Collection-$(date +%F)

Are these supposed to be 2 completely different files in different places?
Also, in the unusual situation that you run this script around midnight, you could end up with differently named files
with your data split over the 2 of them (just a thought)

Something you might like to look at with your yes / no question (apart from handling incorrectly entered options) is
that you can test for a single response by controlling the format.
Example:
Code:

read ans
case ${ans^^} in # alternative is ,,
YES) <do blah>

^^ convert to all upper case and ,, to convert to all lower case

jv2112 12-19-2011 04:57 AM

Thanks for the suggestion on the case statement Grail. I'll hold onto that one for future use. Also thanks for catching the typo.

Works as expected now ........ :cool:

Quote:

#! /bin/bash
clear
figlet Collection List
echo -e "\e[00;34mWhat parent directory does your collection start ? \e[00m"
read start
echo
echo -e "\e[00;31m ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \e[00m"
echo
echo -e "\e[00;33m What do you want to call your list ? \e[00m"
read Collection
touch /home/$USER/"$Collection-$(date +%F)"
ls -R $start | while read file; do echo "${file%.*}" >>/home/$USER/"$Collection-$(date +%F)"; done
echo
echo -e "\e[00;31m---- Preparing File : $Collection ---- \e[00m"

sleep 5
echo -e "\e[00;31m ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \e[00m"
echo -e "\e[44;37m Do you want to view \e[44;33m$Collection. \e[00;34m--Yes / No - \e[00m"
read ans
case ${ans^^} in
# ^^ convert to all upper case and ,, to convert to all lower case

YES) cat /home/$USER/"$Collection-$(date +%F)" | less ;;
*) figlet Exiting ...
sleep 3
cowsay "Goodbye $USER"
;;
esac




grail 12-19-2011 06:45 AM

Sorry to still be a bit picky (I am old so I have been told some times it is my prerogative :) ), but your file
construct still has the time issue. My suggestion would be to set it in a variable and use at your leisure or
open the file for input at point of creation. Also, redirecting into the file will create it so the touch is not required either.
An example of the first option would be:
Code:

read Collection

collection_file_name="/home/$USER/$Collection-$(date +%F)"

ls -R $start | while read file; do echo "${file%.*}" >> "$collection_file_name"; done


jv2112 12-19-2011 09:36 PM

Thanks for the suggestions grail... :)


All times are GMT -5. The time now is 05:50 AM.