Spaces in filenames screwing things up...


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Spaces in filenames screwing things up...
# 15  
Old 08-03-2012
Quote:
Originally Posted by alister
You may as well use printf correctly anyway. Aside from possible issues with a leading dash with GNU coreutils and bash printf implementations, there would be problems if anything in the filename looks like a format specifier or escape sequence.

Regards,
Alister
Could you possibly educate me on how then? Feel free to PM me so we don't go off topic.

---------- Post updated at 02:34 AM ---------- Previous update was at 02:31 AM ----------

Quote:
Originally Posted by methyl
Forgot to mention that you should use double quotes when calling the script if your parameter contains space characters:

Code:
./scriptnname "directory name"

I believe in coding that type of flaw out. Hence the post.

---------- Post updated at 05:58 AM ---------- Previous update was at 02:34 AM ----------

My updated script... still having some issues

Code:
#!/bin/bash

SRC=$1
TMP=`mktemp`

function main {

	validate	
	run

}

function validate {
	if [[ -z $SRC ]]; then
		printf "You need to supply a source.\n";
		exit 1;
	elif [[ -f $SRC ]]; then
		printf "This is a file! You need to specify a directory.\n";
		exit 1;
	fi
}

function run {

	printf "Please wait...\n";
	find $SRC -type f -iname "*.mp3" > $TMP
	
	while read FILE
	do
		analyze_mp3
	done < $TMP

}

function analyze_mp3 {

	GENRE=`id3v2 -l "$FILE" | grep TCON | awk -F: '{printf $2"\n"}' | sed -e 's_^[[:space:]]*__g' | sed 's_([0-9][0-9][0-9])$__' | sed 's_([0-9][0-9])$__' | sed 's_([0-9])$__'`
	printf "FILE:\t$FILE\n";	
	printf "GENRE:\t$GENRE\n";

}

main

I keep getting errors like this.

Code:
FILE:   /media/Data_Bucket/Audio/Alex_M.O.R.P.H._&_Woody_van_Eyden/hardenergy.lv_(Disc_3)/03_-_A_State_Of_Trance_400_Pre-Reocrded_Guestmix_(18-04-09).mp3
GENRE:
./sync-indus.bash: line 38: printf: `_': invalid format character
FILE:   /media/Data_Bucket/Audio/Alex_Reece/100GENRE:
FILE:   /media/Data_Bucket/Audio/Alex_Twister/We_Will_Rock_You_(Remix)_[256_KBPS]_[Alex_Twister].mp3
GENRE:
./sync-indus.bash: line 38: printf: `_': invalid format character
FILE:   /media/Data_Bucket/Audio/Acetate/100GENRE:
FILE:   /media/Data_Bucket/Audio/Aceyalone_Chairman_Hahn/Reanimation/11_-_WTH_You.mp3
GENRE:
FILE:   /media/Data_Bucket/Audio/Act,_The/Too_Late_at_20/01_-_Too_Late_At_20.mp3
GENRE:  Powerpop

I'm thinking it might have something to do with the % in the file/directory names.

Code:
binary@bitslip:/media/Data_Bucket/Audio/Alex_Reece$ ls -l
total 4
drwx------ 1 binary binary 4096 2011-07-16 00:05 100%_Drum_&_Bass_(Disc_1)
binary@bitslip:/media/Data_Bucket/Audio/Alex_Reece$ cd ../Acetate/
binary@bitslip:/media/Data_Bucket/Audio/Acetate$ ls -l
total 0
drwx------ 1 binary binary 0 2011-07-16 00:01 100%_Drum_&_Bass_(Disc_2)

Is that something that is best dealt with using sed?
# 16  
Old 08-03-2012
Quote:
Originally Posted by alister
You may as well use printf correctly anyway. Aside from possible issues with a leading dash with GNU coreutils and bash printf implementations, there would be problems if anything in the filename looks like a format specifier or escape sequence.
Quote:
Originally Posted by Binary Buddha
Could you possibly educate me on how then? Feel free to PM me so we don't go off topic.
Not only is it not off-topic, incorrect use of printf is the root of your problem.


Quote:
Originally Posted by Binary Buddha
Code:
	printf "FILE:\t$FILE\n";	
	printf "GENRE:\t$GENRE\n";

The first argument to printf is a format string. A conversion specifier (aka format specifier) is a sequence of characters within a format string which begins with a %.

What will be the format of the output of those printf commands? It's impossible to say. You have handed over control of the format string to external sources. How printf will behave and how many arguments it will require depend on the type and number of conversion specifiers in the format string. The type and number of specifiers in turn depends on the variable values $FILE and $GENRE.

You want to be very careful about what you allow into that first argument to printf.


Quote:
Originally Posted by Binary Buddha
I keep getting errors like this.

Code:
./sync-indus.bash: line 38: printf: `_': invalid format character

I'm thinking it might have something to do with the % in the file/directory names.
You are correct.


Quote:
Originally Posted by Binary Buddha
Code:
binary@bitslip:/media/Data_Bucket/Audio/Alex_Reece$ ls -l
total 4
drwx------ 1 binary binary 4096 2011-07-16 00:05 100%_Drum_&_Bass_(Disc_1)
binary@bitslip:/media/Data_Bucket/Audio/Alex_Reece$ cd ../Acetate/
binary@bitslip:/media/Data_Bucket/Audio/Acetate$ ls -l
total 0
drwx------ 1 binary binary 0 2011-07-16 00:01 100%_Drum_&_Bass_(Disc_2)

Is that something that is best dealt with using sed?
No. There's no need to mangle the file names just to print them out. What you need to do is not allow arbitrary data into your format string.

Corrected printf statements:
Code:
	printf 'FILE:\t%s\n' "$FILE";	
	printf 'GENRE:\t%s\n' "$GENRE";

Note how the format string is now invariant. Whatever the value of the variables, the format string never changes (a point driven home by switching to strong single-quotes).

The same bug lurks in your awk one-liner:

Quote:
Originally Posted by Binary Buddha
Code:
awk -F: '{printf $2"\n"}'

Make $2 an argument and in the format string replace it with an appropriate conversion specifier (%s in this case).

In shell scripting, this type of error is typically nothing worse than garbled output, but a format string bug in a language like C can be a major security issue. For more info, see Uncontrolled format string.

Regards,
Alister

Last edited by alister; 08-03-2012 at 09:18 AM..
# 17  
Old 08-04-2012
Quote:
Originally Posted by alister
The same bug lurks in your awk one-liner:



Make $2 an argument and in the format string replace it with an appropriate conversion specifier (%s in this case).
I tried to fix it but it gave me errors

Code:
Please wait...
awk: {printf %sn "$2"}
awk:         ^ syntax error
FILE:   /media/Data_Bucket/Audio/(val)Liam/Vampire_Sunrise_(Disc_1)/04_-_As_Is.mp3_CBR.mp3
GENRE:  
awk: {printf %sn "$2"}
awk:         ^ syntax error
FILE:   /media/Data_Bucket/Audio/)eib(/BC Recordings (BCRUK001)/Dogfight.mp3
GENRE:  
awk: {printf %sn "$2"}
awk:         ^ syntax error


The modified function...
Code:
function analyze_mp3 {

        GENRE=`id3v2 -l "$FILE" | grep TCON | awk -F: '{printf '%s\n' "$2"}' | sed -e 's_^[[:space:]]*__g' | sed 's_([0-9][0-9][0-9])$__' | sed 's_([0-9][0-9])$__' | sed 's_([0-9])$__'`
        printf 'FILE:\t%s\n' "$FILE";
        printf 'GENRE:\t%s\n' "$GENRE";

}


What am I missing? Yeah this conversion string thing is new to me.
# 18  
Old 08-04-2012
You can't use single quotes inside double quotes. They don't nest -- it's treated as the end of the single quote.

Awk doesn't use single quotes anyway. Use double quotes.

You can't use variables inside quotes in awk. Get rid of those quotes around $2.

You forgot the comma after the first argument, and the brackets.

You can also get rid of that grep by putting the regex inside awk itself. That's done really easily.

Code:
awk -F: '/TCON/ { printf("%s\n", $2) }'

In fact, you can replace that entire enormous pipe-chain with it. awk is a whole programming language, not a glorified cut. And you can match the numbers in one regex instead of three by using ?, a specifier like * that means "zero or one of the previous character".

Code:
awk -F: '/TCON/ {
        gsub(/[ \t]*/, "", $2); # Strip whitespace
        gsub(/_[0-9]?[0-9]?[0-9]$/, "__", $2); # Replace _123 at the end with __
        printf("%s\n", $2); }'

This User Gave Thanks to Corona688 For This Post:
# 19  
Old 08-05-2012
@Corona688 Think he wanted to strip leading whitespace, and a bracketed string of up to 3 digits from end of field 2 (he was using _ as the sed delimiter).

This slight change should cover it:
Code:
GENRE=`id3v2 -l "$FILE" | awk -F: '/TCON/ {
        gsub(/^[ \t]*/, "", $2); # Strip leading whitespace
        gsub(/\([0-9]?[0-9]?[0-9]\)$/, "", $2); # Remove bracketed string up to 3 digits from the end
        printf("%s", $2); }'`


Last edited by Chubler_XL; 08-05-2012 at 09:56 PM..
These 2 Users Gave Thanks to Chubler_XL For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Reading filenames with spaces

Hello I've got a certain no. of files in a directory whose names I'm reading and redirecting into a temporary text file using the command below: ls -l | grep ^- | awk '{print $9}'However, whenever the file names contain spaces the above command considers only the part of the file name up to... (5 Replies)
Discussion started by: S. BASU
5 Replies

2. Shell Programming and Scripting

Remove spaces in filenames

Hi, I have files like below, In files coming as spaces. Before transfering those files into ftp server. I want to remove the spaces and then can transfer the files into unix server. e.g: filenames are 1) SHmail _profile001_20120908.txt 2) SHmail_profile001 _20120908.txt 3) sh... (3 Replies)
Discussion started by: kirankumar
3 Replies

3. Shell Programming and Scripting

removing spaces in filenames

I have a problem mounting images because of the spaces in the filenames. Does anyone know how to rename files by removing the spaces with the find command? find Desktop/$dir -name "*.dmg" -print -exec ??? (4 Replies)
Discussion started by: ianebaj
4 Replies

4. Shell Programming and Scripting

awk and spaces in filenames

Hey there, this is my first post and I'll try to explain my situation as best I can.Here is a sample of the input file: ADO Sample.h,v ADO Sample 2010-05-21 lyonsb /repository/patents/TSCommon/OpenSource/Dundass/ug6mfc/DataSources/Ado/ADO Sample ADO SampleDoc.h,v ADO SampleDoc 2010-05-21... (3 Replies)
Discussion started by: rodan90
3 Replies

5. Shell Programming and Scripting

Looping through filenames with spaces

I need to loop through the files in a directory and process the files. But some of the filenames contain spaces. Here is a little test script I've been using to experiment. (I'm not really going to call 'echo', I'm doing some other processing.) Everything I try fails. How can I do this??... (7 Replies)
Discussion started by: KenJackson
7 Replies

6. Shell Programming and Scripting

spaces in filenames

Hi I hope someone will be able to resolve this little teaser! I am running a script for file in `ls directory` do echo "$file" ...other code here.... done this works fine unless we receive a file with a name which has a space in it ie "filena me" (I know its not good... (8 Replies)
Discussion started by: Bab00shka
8 Replies

7. Shell Programming and Scripting

spaces in filenames, for do

Hi All, I see similar problems in past threads but so far no answers have worked for me. I am trying to write a script which parses a txt file that contains one filename per line, then finds those files on the local disk and copies them to a specified directory. What I have: ... (4 Replies)
Discussion started by: naviztirf
4 Replies

8. Shell Programming and Scripting

Unix filenames and spaces

I have files on my unix boxes that users have created with spaces. Example: /tmp/project plan ls -l "/tmp/project plan" works fine. $/tmp>ls -l "/tmp/project plan" -rw-r--r-- 1 root other 0 Jan 31 12:32 /tmp/project plan I created a file called test and put just the... (2 Replies)
Discussion started by: x96riley3
2 Replies

9. Shell Programming and Scripting

how to handle spaces in filenames

I'm trying to do something like that: for $filename in `ls -1` do some_command $filename done but it doesn't work properly for file names with spaces, for...in splits at spaces. Anyway around? (4 Replies)
Discussion started by: rayne
4 Replies

10. Shell Programming and Scripting

spaces in filenames

I have a problem with the script below #!/bin/sh for vo in `find -maxdepth 1 -type f -regex "^\./*$"` do ls -l "$vo" some other commands done It works fine until `find ...` returns files with spaces. I've tryed to change IFS but haven't succeed Any solutions? (4 Replies)
Discussion started by: Hitori
4 Replies
Login or Register to Ask a Question