Teb*_*ebe 1 shell bash quoting
经过一些操作后,我得到了包含命令的文件,我很高兴能够执行这些命令。
输入文件(文件名为 inp2.txt):
"02 - Beautiful Emptiness.mp3"
"02 - Come. mp3"
"02 - Go For It.mp3"
Run Code Online (Sandbox Code Playgroud)
代码:
#!/bin/bash
exec 4<inp2.txt # opening file via descriptor
while read LINE <&4; do
printf "%s\n" "$LINE" # just to watch that command is proper
$LINE # execute command
done
Run Code Online (Sandbox Code Playgroud)
编辑:抱歉,我省略了我认为对理解不重要的重要代码部分。完整代码:
#!/bin/bash
IFS='
'
declare LINE
declare BUF
declare a
a=1
rm inp2.txt # delete previous version of file
exec 3< inp.txt # open descriptor for a file()content of it is written above
while read LINE <&3; do # read it
printf "mv ""$LINE"" %s\n" """$a"".mp3" >> inp2.txt
# form a command and output it to the file, just to make sure that I got a command that I really want
let "a++" # increment number that will be a part of new unique name
done
exec 4<inp2.txt #open again descriptor with ready commands
while read LINE <&4; do
printf "%s\n" "$LINE" # check again
$LINE # here it should be executed, but I get mistakes that is pointed down
done
exit 0
Run Code Online (Sandbox Code Playgroud)
输出:
似乎命令是正确的,但是出了点问题,我无法弄清楚到底出了什么问题。
您发布的脚本、数据文件和输出不一致。脚本和数据文件都不包含mv
,但您的屏幕截图包含。此外,您的屏幕截图提到了您发布的脚本没有的第 28 行。当您向我们提供不一致的信息时,很难查明您的问题。
也就是说,您正在尝试做两件事情中的一件,而这两件事情都不能像您尝试的那样工作。
如果输入文件包含类似的行
mv "02 - Beautiful Emptiness.mp3" 1.mp3
Run Code Online (Sandbox Code Playgroud)
那么它实际上是一个shell脚本。与其逐行读取,不如将其作为 shell 脚本执行。确保您可以信任此文件,因为您将执行其中的任何内容,包括rm -rf ~
或其他一些内容。
. inp2.sh
Run Code Online (Sandbox Code Playgroud)如果输入文件包含类似的行
mv "02 - Beautiful Emptiness.mp3" 1.mp3
Run Code Online (Sandbox Code Playgroud)
那么你阅读它的方式就行不通了。read LINE
执行以下操作:
\
);LINE
为读取的行的串联,减去换行符。当 shell 执行命令时$LINE
,它会做它在看到引号外的变量替换时总是做的事情,即:
IFS
);听起来没用?这是。请注意,这里没有关于引号的内容:引号是 shell 语法的一部分,它们不是 shell 扩展规则的一部分。
您可能应该inp2.txt
包含一个文件名列表,每行一个。请参阅为什么经常使用 `while IFS= read`,而不是 `IFS=; 阅读时..`?了解如何从文件中读取行列表。你会想要类似的东西
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
Run Code Online (Sandbox Code Playgroud)
为了完整起见,我会提到另一种可能性,但我不推荐它,因为它很繁琐,而且它不会让你做你似乎在做的事情。像这样的文件
. inp2.sh
Run Code Online (Sandbox Code Playgroud)
然后它可以被xargs
命令读取。输入到xargs
以空格分隔的元素列表,它可以是由单引号包围的文字(可能包含空格)、由双引号包围的文字(可能包含空格)或可能包含反斜杠转义的未加引号的文字(\
引用下一个字符)。请注意,该xargs
语法与 shell 可能识别的任何内容都不同。
归档时间: |
|
查看次数: |
20819 次 |
最近记录: |