LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 08-06-2009, 11:31 AM   #1
dai_bach
LQ Newbie
 
Registered: Jan 2008
Distribution: Ubuntu
Posts: 2

Rep: Reputation: 0
mv: target `filename' is not a directory


I'm trying to write a short script that changes the file names in the folders containing music (mp3) files. The current format is often along the lines of:
"Artist Name - Album Name - tracknum - Trackname.mp3"
and I'd like to shorten this to just:
"tracknum Trackname.mp3"

So, I've tried the following approach
Code:
for i in *.mp3; do
  j=`echo $i | cut -d "-" -f3`; #results in "tracknum"
  k=`echo $i | cut -d "-" -f4`; #results in "Trackname.mp3"
  mv $i $j$k;
done
but I get the error:
Code:
mv: target `Trackname.mp3' is not a directory
I'm not expecting it to be a directory! As far as I'm aware, $j$k should give me "tracknum Trackname.mp3". Indeed, this is the result of
Code:
echo $j$k
Could someone please tell me where I'm going wrong or how to solve my problem?

Cheers
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 08-06-2009, 11:42 AM   #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
I'll bet the problem is spaces in your filenames. They can really mess up scripting. Most *nix users learn to avoid them in filenames whenever possible.

Add this to the start of your script. It changes the internal field separator to a newline only, and your script will treat spaces as just another character from then on.
Code:
#!/bin/bash

IFS='
'

<your script>
Also, take some time to learn about how quotes work in shells and scripts. Surrounding your variables in double-quotes will generally work too. I usually prefer changing the IFS though, as it's more foolproof.

Last edited by David the H.; 08-06-2009 at 11:48 AM. Reason: added final note
 
4 members found this post helpful.
Old 08-07-2009, 01:07 PM   #3
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
So I take it it worked then.
 
Old 08-08-2009, 02:00 AM   #4
dai_bach
LQ Newbie
 
Registered: Jan 2008
Distribution: Ubuntu
Posts: 2

Original Poster
Rep: Reputation: 0
Aye, worked a treat. Cheers!
 
Old 11-19-2012, 11:46 PM   #5
fqaiser
LQ Newbie
 
Registered: Nov 2012
Posts: 4

Rep: Reputation: Disabled
Unhappy Install: target p is not a directory

I have an error same as per above 'Title'. In fact i am trying to install aircrack-2.41 on Backtrack 5 which is installed on Virtual Box. It will come to terminal screen when;

I run a command 'root@bt:~/aircrack-2.41# make install'.

In result of this i found following response;

a) install -d /usr/local/bin
b) install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p
c) cap2inv /usr/local/bin

When i try to apply [install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p ] it appears like this;

[root@bt:~/aircrack-2.41#install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p]

install: target p is not a directory

Can somebody please help me to solve this problem?? why p directory is not found?? can i create a p directory myself to complete install??
help me....!!!!!!!!!!!!!!
 
Old 12-19-2012, 02:24 AM   #6
fqaiser
LQ Newbie
 
Registered: Nov 2012
Posts: 4

Rep: Reputation: Disabled
Quote:
Originally Posted by fqaiser View Post
I have an error same as per above 'Title'. In fact i am trying to install aircrack-2.41 on Backtrack 5 which is installed on Virtual Box. It will come to terminal screen when;

I run a command 'root@bt:~/aircrack-2.41# make install'.

In result of this i found following response;

a) install -d /usr/local/bin
b) install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p
c) cap2inv /usr/local/bin

When i try to apply [install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p ] it appears like this;

[root@bt:~/aircrack-2.41#install -m 755 aircrack airdecap arpforge aireplay airodump airmon.sh mergeivs p]

install: target p is not a directory

Can somebody please help me to solve this problem?? why p directory is not found?? can i create a p directory myself to complete install??
help me....!!!!!!!!!!!!!!
My problem has been solved as it is already installed & i use /usr/local/bin to use aircrack. Many Thanks.
 
Old 12-19-2012, 02:14 PM   #7
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
First of all, please don't re-open old threads unless you have something substantial to add to that discussion, such as a correction or updated information. If you have a new question of your own, start a new thread and refer back to the old one if necessary. Thanks.

Besides, I don't think your question has anything directly to do with the original subject here. His problem was with improperly quoted variables leading to word-splitting in the arguments, while yours seems to have something to do with either the syntax of your install command or the conditions of the directory you passed to it. But I'm not familiar with that comman, so I can't say.


But you have given me an opportunity to update one of my old posts. After several more years of experience, I would no longer give the advice that I did then.

First, I now understand that changing IFS should be generally avoided, due to possible obscurity in what the code is doing, and that proper quoting is usually the best solution.

Second, when you do need to change IFS to newline or other non-printing characters, you can use ansi-c style quoting:

Code:
IFS=$'\n'
Third, I would recommend the use of built-in string manipulation techniques, rather than cut.

Code:
for fname in *.mp3; do

	newname="${fname#* - * - }"	#results in "tracknum - trackname.mp3"
	newname="${newname// - / }	#changes the " - " to " "
	mv "$fname" "$newname"

done
 
Old 12-19-2012, 11:49 PM   #8
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,657

Rep: Reputation: 255Reputation: 255Reputation: 255
Quote:
Originally Posted by dai_bach View Post
I'm trying to write a short script that changes the file names in the folders containing music (mp3) files. The current format is often along the lines of:
"Artist Name - Album Name - tracknum - Trackname.mp3"
and I'd like to shorten this to just:
"tracknum Trackname.mp3"

So, I've tried the following approach
Code:
for i in *.mp3; do
  j=`echo $i | cut -d "-" -f3`; #results in "tracknum"
  k=`echo $i | cut -d "-" -f4`; #results in "Trackname.mp3"
  mv $i $j$k;
done
but I get the error:
Code:
mv: target `Trackname.mp3' is not a directory
I'm not expecting it to be a directory! As far as I'm aware, $j$k should give me "tracknum Trackname.mp3". Indeed, this is the result of
Code:
echo $j$k
Could someone please tell me where I'm going wrong or how to solve my problem?

Cheers









you need :

Code:
find -iname "*.mp3" | while read -r i ; do   echo "$i" ; done
or use this:


Code:
 
#!/bin/sh  


echo "#############################################"
echo "SHELL : $SHELL"
echo "BASH : $BASH"
echo "TERM : $TERM"
DATENOW=`date +%Y%m%d-%H%M%S` 
# last argument
LASTARG=`echo "$@" | awk ' { print $NF  }  '`
# penultimate argument
num_args=$# 
num_args_max=$num_args
let num_args=$num_args-1 
PENUARG=` echo "$@" | awk -v vk=$num_args ' { print $vk  }  ' `
TRG="$LASTARG"
[ ! -d ~/.config/bashmv ] && mkdir -p ~/.config/bashmv
echo "$DATENOW - $@" >> ~/.config/bashmv/bash-ops-inputs.log 
echo "#############################################"







ProcedureStartCopyOneFile() {
  echo "*** COPY ***"
  echo "File not exists : $FILETRG" >> ~/.config/bashmv/bashmv.log
  echo -en "\r Copying ($i) (...)"
  echo "$i" | cpio -pvdmu "$TRG"
  echo -en "\r Copied ($i)."
  TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
  SRSS=` du -hs "$i" --apparent-size | cut -f 1 ` 
  if  [ ! -d  "$i" ] &&  [ "$SRSS" != "$TRSS" ] ; then 
    echo "Different size: $FILETRG"
    echo "** WARNING **"
    echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
    echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
    exit
  else
    echo -en "\r Copied ($i) [OK]"
  fi
  echo "*** COPY OK ***"
  echo ".*.*"
}







ProcedureCopying() {

 echo "> Parameters: Source: $SRC  => Target: $TRG"


if [ -f "$SRC" ] || [  -d "$SRC" ] ; then 
  echo "Source: $SRC"
else
  echo "Directory or file source $SRC not found."
  exit
fi

if [ "$TRG" = "" ] ; then 
  exit
fi





if [ "$BASH" != "/bin/bash" ] ; then
  echo "Warning: You should use BASH : /bin/bash !"
  exit
else 
  echo "Intpreter BASH: $BASH [OK] "
fi





echo "** START ** "



[ ! -d  "$TRG" ] && mkdir -p "$TRG"
if [ "$LASTARG" = "--debug" ] ; then
  find "$SRC" -print
  exit
fi

find "$SRC" -print | grep -v "^$\|^#" | while read -r i ; do 
# echo "Processing $i"

FILETRG="${TRG}/${i}"
DATENOW=`date +%Y%m%d-%H%M%S` 
echo "> Start: .*.* ($i)"
if [ !  -f "$FILETRG" ] && [ ! -d  "$i"  ] ; then 
  echo ".*.*"
  echo "*** COPY ***"
  echo "File not exists : $FILETRG" >> ~/.config/bashmv/bashmv.log
  echo "$i" | cpio -pvdmu "$TRG"
  TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
  SRSS=` du -hs "$i" --apparent-size | cut -f 1 ` 
  if  [ ! -d  "$i" ] &&  [ "$SRSS" != "$TRSS" ] ; then 
    echo "Different size: $FILETRG"
    echo "** WARNING **"
    echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
    echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
    exit
  else
    echo "Copied ($i) [OK]"
      echo "     - Del file: $i since ok"
      rm "$i"
  fi
  echo "*** COPY OK ***"
  echo ".*.*"


elif [  -d "$i" ] ; then
  mkdir -p "$FILETRG"
  echo "Creating $FILETRG"

elif [ ! -d "$i" ] ; then
  TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
  SRSS=` du -hs "$i" --apparent-size | cut -f 1 ` 
  # echo "Source: $SRSS vs $TRSS"


  if  [ -d  "$i" ] ; then
    echo "Directory."
  fi

  if  [ ! -d  "$i" ] ; then
    if [ -f "$FILETRG" ] && [ "$SRSS" = "$TRSS" ] ; then 
      echo "file $FILETRG exists. [Same size]"
      echo "     - Del file: $i since ok"
      rm "$i"
    fi

    if   [ "$SRSS111kkk" = "$TRSS" ] ; then 
      echo "Different size: $FILETRG"
      echo "** WARNING **"
      echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
      echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
      FILETRGERROR="${TRG}/Error/${i}"
      [ ! -d  "$TRG/Error" ] && mkdir -p "$TRG/Error"
      echo "$TRSS" | cpio -pvdmu   "$TRG/Error/${DATENOW}-${i}"
      echo "Error. Stopped"
      exit
    fi
  fi
fi



done

echo "Completed. Finished!"


if [ "$LASTARG" = "--rm" ] ; then 
  echo "Delete the directory: $SRC [y/n] ? "
  read inpud
  [ "$inpud" = "n" ] && exit
  rm -rf "$SRC"
fi


exit

echo "Calculating... "
echo "Cmd:  du -hs $SRC"
SIZE1=` du -hs "$SRC" | cut -f 1 `
echo "Source: $SIZE1"

echo "Cmd:  du -hs $TRG"
SIZE2=` du -hs "$TRG" | cut -f 1 `
echo "Target: $SIZE2"

if [ "$SIZE1" = "$SIZE2" ] && [ "$LASTARG" = "--rm" ] ; then 
  echo "Delete the directory: $SRC [y/n] ? "
  read inpud
  [ "$inpud" = "n" ] && exit
  rm -rf "$SRC"
fi

} 











counter=1
echo "Args: $num_args"
seq 1 1 "$(( $num_args +1))" | while read -r each ; do
  if [ $counter -lt $num_args_max ] ; then
     SRC=` echo "$@" | awk -v vk=$counter ' { print $vk  }  ' `
     echo "> $each : $SRC"
     echo "Copying : $SRC to $TRG"
     ProcedureCopying
     echo  
  fi
  counter=$(( $counter +1))
done
exit



# this does mv or backup
 
Old 12-20-2012, 06:20 AM   #9
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
@Xeratul, This is what I was talking about. The thread is over three years old, and I'm sure the OP has long ago moved on to new things. The only reason to add anything new is to help others coming across it later.


As for your suggestions, find is only necessary if you need to search recursively or otherwise match files by criteria that simple globbing can't handle, and even then you shouldn't just pipe the results directly into a loop like that.

Unix file paths can contain any character (except one), so there's always a chance that one can contain an embedded newline. The exception is the null, which is why it's recommended for use as the delimiting character in cases like this.

How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?
http://mywiki.wooledge.org/BashFAQ/001

How can I find and deal with file names containing newlines, spaces or both?
http://mywiki.wooledge.org/BashFAQ/020

There are other issues involved too. If your changes include modifying the pathname, for example, you need to be sure to use the -depth option to process things in a safe order. And anything done in a pipe chain may suffer from subshell-related variable scoping.


How can I rename all my *.foo files to *.bar, or convert spaces to underscores, or convert upper-case file names to lower case?
http://mywiki.wooledge.org/BashFAQ/030

I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?
http://mywiki.wooledge.org/BashFAQ/024

So to safely use find, something like this would be better:
Code:
while IFS='' read -r -d '' fname ; do
	echo "$fname"
done < <( find . -depth -type f -name '*.mp3' -print0 )
Finally, and I should've mentioned this yesterday, there are a multitude of batch renaming options available, and an unbelievable number of previous discussions on this same topic. If you want to know more, just do a bit of searching in the archives or the web.
 
Old 12-20-2012, 07:58 AM   #10
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,657

Rep: Reputation: 255Reputation: 255Reputation: 255
Quote:
Originally Posted by David the H. View Post
@Xeratul, This is what I was talking about. The thread is over three years old, and I'm sure the OP has long ago moved on to new things. The only reason to add anything new is to help others coming across it later.


As for your suggestions, find is only necessary if you need to search recursively or otherwise match files by criteria that simple globbing can't handle, and even then you shouldn't just pipe the results directly into a loop like that.

Unix file paths can contain any character (except one), so there's always a chance that one can contain an embedded newline. The exception is the null, which is why it's recommended for use as the delimiting character in cases like this.

How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?
http://mywiki.wooledge.org/BashFAQ/001

How can I find and deal with file names containing newlines, spaces or both?
http://mywiki.wooledge.org/BashFAQ/020

There are other issues involved too. If your changes include modifying the pathname, for example, you need to be sure to use the -depth option to process things in a safe order. And anything done in a pipe chain may suffer from subshell-related variable scoping.


How can I rename all my *.foo files to *.bar, or convert spaces to underscores, or convert upper-case file names to lower case?
http://mywiki.wooledge.org/BashFAQ/030

I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?
http://mywiki.wooledge.org/BashFAQ/024

So to safely use find, something like this would be better:
Code:
while IFS='' read -r -d '' fname ; do
	echo "$fname"
done < <( find . -depth -type f -name '*.mp3' -print0 )
Finally, and I should've mentioned this yesterday, there are a multitude of batch renaming options available, and an unbelievable number of previous discussions on this same topic. If you want to know more, just do a bit of searching in the archives or the web.
the problem with the above script is that it uses bash:
done < <( find . -depth -type f -name '*.mp3' -print0 )

Your inputs are welcome

Sh could do it one day, would be useful. All my init.d script are based on sh that I employ mostly. I try to stick to sh for minimal install. dont really know why.
 
  


Reply

Tags
mv



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
Longest filename in a directory dresch Linux - Newbie 6 01-05-2007 03:29 PM
How do I stop the filename and directory from printing? BajaNick Linux - Hardware 1 08-31-2004 04:31 PM
read filename from directory newbielinux Linux - Newbie 2 03-02-2004 03:48 PM
samba + target directory robyso Linux - Networking 0 07-11-2003 05:07 AM
Changing to a directory with a space in the filename? guitargeek Linux - General 5 02-13-2003 05:38 PM

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

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