The script, data file and output that you posted are inconsistent. Neither the script not the data file contain mv
, yet your screenshot does. Also, your screenshot mentions a line 28, which the script you posted doesn't have. It's difficult to pinpoint your problem when you give us inconsistent information.
That said, you're trying to do one of two things, neither of which can work the way you're trying.
If the input file contains lines like
mv "02 - Beautiful Emptiness.mp3" 1.mp3
then it's really a shell script. Instead of reading it line by line, execute it as a shell script. Make sure that you can trust this file, since you'll be executing whatever is in there, including rm -rf ~
or some such.
. inp2.sh
If the input file contains lines like
"02 - Beautiful Emptiness.mp3"
then the way you're reading it doesn't work. read LINE
does the following:
- read one line;
- if that line ends with a backslash, remove the backslash and read another line (repeat until a line that doesn't end with a
\
has been read);
- replace all backslash+character sequences by the second character only;
- set
LINE
to the concatenation of the lines read, minus the newlines.
When the shell executes the command $LINE
, it does what it always does when it sees a variable substitution outside quotes, which is:
- split the value of the variable into a list of words at every place where it contains whitespace (assuming the default value of
IFS
);
- treat each word as a glob pattern, and expand it if it matches at least one file.
Sounds useless? It is. And note that there's nothing about quotes in here: quotes are part of the shell syntax, they aren't part of the shell expansion rules.
What you probably should to is have inp2.txt
contain a list of file names, one per line. See Why is `while IFS= read` used so often, instead of `IFS=; while read..`? for how to read a list of lines from a file. You'll be wanting something like
i=1
while IFS= read -r source; do
dir=$(dirname -- "$source")
ext=
case "${source##*/}" in
*.*) ext=.${source##*.};;
esac
mv -- "$source" "$dir/$i$ext"
done <inp2.txt
Just for completeness, I'll mention another possibility, but I don't recommend it because it's fiddly and it won't let you do what you seem to be doing. A file like
"02 - Beautiful Emptiness.mp3" "02 - Come. mp3" foo\ bar.mp3
then it can be read by the xargs
command. The input to xargs
is a whitespace-delimited list of elements, which can be either a literal (possibly containing whitespace) surrounded by single quotes, a literal (possibly containing whitespace) surrounded by double quotes, or an unquoted literal which may contain backslash escapes (\
quotes the next character). Note that the xargs
syntax is unlike anything the shell might recognize.