LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 10-16-2009, 11:51 AM   #1
quanta
Member
 
Registered: Aug 2007
Location: Vietnam
Distribution: RedHat based, Debian based, Slackware, Gentoo
Posts: 724

Rep: Reputation: 101Reputation: 101
mv: target `xyz' is not a directory?


Hi guy,

I have a set of files like that:
Code:
16 mat nai - Jimmy Nguyen [NCT 1188596568].mp3               
Nho ve em - Jimmy Nguyen [NCT 4035860162].mp3
Buon thu qua - Jimmy Nguyen [NCT 9734938264].mp3             
Nho ve em - Jimmy Nguyen [NCT 5629480849].mp3
Chiec nhan ngay xua - Jimmy Nguyen [NCT 1268575536].mp3
Nhung gi toi uoc ao - Jimmy Nguyen [NCT 2820242089].mp3
...
I want to cut the tail to make it to:
Code:
16 mat nai - Jimmy Nguyen.mp3               
Nho ve em - Jimmy Nguyen.mp3
Buon thu qua - Jimmy Nguyen.mp3             
Nho ve em - Jimmy Nguyen.mp3
Chiec nhan ngay xua - Jimmy Nguyen.mp3      
Nhung gi toi uoc ao - Jimmy Nguyen.mp3
...
I try to using a following command:
Code:
$ for f in *; do mv "$f" `echo "$f" | sed 's/ \[NCT [0-9]*\]//'`; done
or:
Code:
$ for f in *; do mv "$f" `echo "$f" | sed 's/\(.*\) \[NCT [0-9]*\].mp3$/\1.mp3/'`; done
but it didn't work:
Quote:
mv: target `Nguyen.mp3' is not a directory
I don't know why? I think it related to above rule. Can anyone help me to explain that.

Thanks in advance,

Last edited by quanta; 02-19-2012 at 03:47 AM.
 
Old 10-16-2009, 03:12 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
The problem is most likely the spaces in the filenames. Your shell treats them as word separators, so your mv command sees the final string as being a directory name to move the rest of the entries into. Double-quoting the string that generates the new filename will probably fix it.

But my favorite way to handle spaces (other than simply not putting them in filenames to begin with) is to temporarily change the shell's internal field separator so that it doesn't treat them as places to divide words.
Code:
oldIFS=$IFS   #first save the current values (default is space, tab, newline)

IFS='
'             #changes the separator to newline only

<Run your commands here>

IFS=$oldIFS   #reset the initial values
PS: Instead of this:
Code:
`echo "$f" | sed 's/ \[NCT [0-9]*\].mp3$//'`
Try this:
Code:
"$(sed 's/ \[NCT [0-9]*\].mp3$//')" <<<"$f"
The <<< here string directs the output of the variable directly to stdin, meaning you don't have to use echo and pipes. And $() is the recommended way to nest commands. Using ` backticks is discouraged.

(assuming you're using bash, of course)


Edit again: Instead of using sed, try parameter substitution.
Code:
$ for f in *; do mv "$f" "${f% [*}.mp3"; done
${f% [*} will remove everything from " [" (space+bracket) to the end of the the variable. Then just re-add the extension and you're done.

Last edited by David the H.; 10-16-2009 at 03:29 PM.
 
Old 10-16-2009, 08:42 PM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
if you have Python and don't mind a script for that, you use the script here
Code:
# ls -1
16 mat nai - Jimmy Nguyen [NCT 1188596568].mp3
Buon thu qua - Jimmy Nguyen [NCT 9734938264].mp3
Chiec nhan ngay xua - Jimmy Nguyen [NCT 1268575536].mp3
Nho ve em - Jimmy Nguyen [NCT 4035860162].mp3
Nho ve em - Jimmy Nguyen [NCT 5629480849].mp3
Nhung gi toi uoc ao - Jimmy Nguyen [NCT 2820242089].mp3

# python filerenamer.py -p " \[.*\]" -e "" -l "*mp3"
==>>>>  [ /home/test/Chiec nhan ngay xua - Jimmy Nguyen [NCT 1268575536].mp3 ]==>[ /home/test/Chiec nhan ngay xua - Jimmy Nguyen.mp3 ]
==>>>>  [ /home/test/Nho ve em - Jimmy Nguyen [NCT 4035860162].mp3 ]==>[ /home/test/Nho ve em - Jimmy Nguyen.mp3 ]
==>>>>  [ /home/test/Nho ve em - Jimmy Nguyen [NCT 5629480849].mp3 ]==>[ /home/test/Nho ve em - Jimmy Nguyen.mp3 ]
==>>>>  [ /home/test/16 mat nai - Jimmy Nguyen [NCT 1188596568].mp3 ]==>[ /home/test/16 mat nai - Jimmy Nguyen.mp3 ]
==>>>>  [ /home/test/Buon thu qua - Jimmy Nguyen [NCT 9734938264].mp3 ]==>[ /home/test/Buon thu qua - Jimmy Nguyen.mp3 ]
==>>>>  [ /home/test/Nhung gi toi uoc ao - Jimmy Nguyen [NCT 2820242089].mp3 ]==>[ /home/test/Nhung gi toi uoc ao - Jimmy Nguyen.mp3 ]
remove the -l option to commit changes.
 
Old 10-16-2009, 09:08 PM   #4
vonbiber
Member
 
Registered: Apr 2009
Distribution: slackware 14.1 64-bit, slackware 14.2 64-bit, SystemRescueCD
Posts: 533

Rep: Reputation: 129Reputation: 129
I just pasted your lines into a test.txt
Code:
16 mat nai - Jimmy Nguyen [NCT 1188596568].mp3
Nho ve em - Jimmy Nguyen [NCT 4035860162].mp3
Buon thu qua - Jimmy Nguyen [NCT 9734938264].mp3
Nho ve em - Jimmy Nguyen [NCT 5629480849].mp3
Chiec nhan ngay xua - Jimmy Nguyen [NCT 1268575536].mp3
Nhung gi toi uoc ao - Jimmy Nguyen [NCT 2820242089].mp3
and I ran these seders on it and got the following output
Code:
$ sed 's? \{1,\}\[?[?' test.txt |\
> sed 's?^\([^\[]*\)\[[^.]*?\1?'
16 mat nai - Jimmy Nguyen.mp3
Nho ve em - Jimmy Nguyen.mp3
Buon thu qua - Jimmy Nguyen.mp3
Nho ve em - Jimmy Nguyen.mp3
Chiec nhan ngay xua - Jimmy Nguyen.mp3
Nhung gi toi uoc ao - Jimmy Nguyen.mp3
if your files are all in the same directory you could do this
Code:
for f in *.mp3
  g="$(echo $f |sed 's? \{1,\}\[?[?' |\
    sed 's?^\([^\[]*\)\[[^.]*?\1?')"
  if [ "$f" != "$g" ]; then
     mv "$f" "$g"
  fi
done
 
Old 10-16-2009, 11:06 PM   #5
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
in bash you can do something like this:
Code:
#!/bin/bash

shopt -s extglob

for F in *; do
	TITLE=${F%%?( )-*}
	ARTIST=${F##*-?( )}
	ARTIST=${ARTIST%.*([[:alpha:]])}
	ARTIST=${ARTIST/[NCT *([[:digit:]])]}
	EXT=${F##*.}

	echo "$F" "->" "$TITLE - $ARTIST.$EXT"		# optional

	mv "$F" "$TITLE - $ARTIST.$EXT"
done
i can't test the code yet. if you try it, please tell me if it works.
 
Old 10-18-2009, 08:37 AM   #6
quanta
Member
 
Registered: Aug 2007
Location: Vietnam
Distribution: RedHat based, Debian based, Slackware, Gentoo
Posts: 724

Original Poster
Rep: Reputation: 101Reputation: 101
Quote:
Originally Posted by David the H. View Post
The problem is most likely the spaces in the filenames. Your shell treats them as word separators, so your mv command sees the final string as being a directory name to move the rest of the entries into. Double-quoting the string that generates the new filename will probably fix it.
Thanks for your explain.
Quote:
Originally Posted by David the H. View Post
But my favorite way to handle spaces (other than simply not putting them in filenames to begin with) is to temporarily change the shell's internal field separator so that it doesn't treat them as places to divide words.
Code:
oldIFS=$IFS   #first save the current values (default is space, tab, newline)

IFS='
'             #changes the separator to newline only

<Run your commands here>

IFS=$oldIFS   #reset the initial values
I know this way, but I always want to do that using one-line command.
Quote:
Originally Posted by David the H. View Post
PS: Instead of this:
Code:
`echo "$f" | sed 's/ \[NCT [0-9]*\].mp3$//'`
Try this:
Code:
"$(sed 's/ \[NCT [0-9]*\].mp3$//')" <<<"$f"
The <<< here string directs the output of the variable directly to stdin, meaning you don't have to use echo and pipes. And $() is the recommended way to nest commands. Using ` backticks is discouraged.

(assuming you're using bash, of course)
Oh, now I know about here string, but can you show me a full command to do this?
Quote:
Originally Posted by David the H. View Post
Edit again: Instead of using sed, try parameter substitution.
Code:
$ for f in *; do mv "$f" "${f% [*}.mp3"; done
${f% [*} will remove everything from " [" (space+bracket) to the end of the the variable. Then just re-add the extension and you're done.
Thanks again. I think I need to re-read the ABS Guide.

@ghostdog74: I am learning Python too, I will consider it later.

@vonbiber, konsolebox: thanks for your help. But as I said above, I want to do that using one-line command.

****************************************************************

Another question from a my friend, seem to more relate to title of this topic:

Output from jobs -l:
Code:
[1]+  7989 Running                 okular sed.stream.editor.cheat.sheet.pdf &
He want to get PID (7989). He know a better command with awk:
Code:
$ jobs -l | awk '{ print $2 }'
but he tried another command with sed:
Code:
jobs -l | sed -n 's/^\[[0-9]*\].*\([0-9]*\).*$/\1/p
and it didn't work, it return a blank line. Can anyone explain that for us?

Last edited by quanta; 10-19-2009 at 10:34 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Perl - Can't use string ("html") as an ARRAY ref while "strict refs" OldGaf Programming 9 08-11-2009 11:14 AM
Regular expression matching , match "error string" but not "other error" jmcmillan Programming 3 07-07-2008 09:50 AM
"Permission denied" and "recursive directory loop" when searching for string in files mack1e Linux - Newbie 5 06-12-2008 07:38 AM
A single regex to match anything with ".aac" or ".mp3" at the end ? lumix Linux - General 9 05-09-2008 01:11 AM
Sed/Awk: print lines between n'th and (n+1)'th match of "foo" xaverius Programming 17 08-20-2007 11:39 AM

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

All times are GMT -5. The time now is 04:35 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