因此,我创建了一个bash脚本,它递归地搜索包含您引入的单词的文件,然后创建一个与引入的变量同名的文件夹(如果该文件夹不存在),最后它将所有满足该单词的文件复制到新文件夹中。
例如,如果我有一个名为“files_1906”的文件夹,其中有一个名为“hello_1906.pdf”的文件,然后有另一个名为“hello”的文件夹(不在第一个文件夹中),其中有一个名为“1906 hello”的文件,如果我引入:.sh program_name.sh“1906”,它应该创建一个名为1906的文件夹,并在其中复制两个文件。
但现在我只设法创建文件夹,它不复制文件。
下面是完整的代码:
#!/bin/bash
currentDir=$(pwd)
for var in "$@"
do
countCurrentWord=$(find . -type f -name "$var" | grep "$var" | wc -l)
echo -e "$countCurrentWord"
echo -e "Number of files matching the keyword $var: $countCurrentWord"
if [[ $countCurrentWord -gt 0 ]]
then
if [[ -d $currentDir/$var ]]
then
echo -e "the folder $var already exists, copying the files...\n"
else
mkdir "$currentDir"/"$var"
echo -e "the folder $var does not exist, creating the folder and copying the files...\n"
fi
IFS=$'\n'
array=$(find . -type f -name "$var")
declare -p array > /dev/null 2>&1
declare -a array > /dev/null 2>&1
length=${#array[@]}
for ((i=0; i < length; i++))
do
cp "${array[i]}" "$currentDir"/"$var"/ > /dev/null 2>&1
echo -e "hello world"
done
else
echo -e "no files found, no move will be made.\n"
fi
done
控制台将返回以下内容:
首先,它表示$countCurrentWord = 0,这没有任何意义,因为存在包含“1906”的文件
但这就是问题所在:
程序忽略大于0的值,开始循环,创建一个名为1906的文件夹,但之后,它不复制文件,一旦创建,它就保持为空。我还从第二个循环中得到了hello world。
那么,我们如何解决这个问题,使它做它的工作和复制文件?
我已经尝试了文件名只有“1906”(也不工作),但脚本应该能够阅读文件的全名,并辨别是否包含关键字介绍。我不知道我有一个错字或任何东西,我没有在bash脚本的经验
我希望我解释得足够好,这样你们就可以帮助我,谢谢你们的努力!
2条答案
按热度按时间nfeuvbwi1#
完全重写:对每个提交的单词只运行一次
find
,并使用reliablebash变量存储找到的文件名。shopt -s extglob
和find !($var)
,避免find
浏览名为$var
的文件夹。for var; do
中,常见情况in "$@"
是 implicit。cp -ait "/path/to/target" "${array[@]}"
是可靠,可以使用特殊的文件名等等。我没有添加
echo "hello world"
命令,但您可以随意添加v
标志到cp
命令:...和/或覆盖前询问的
i
标志:bnl4lu3b2#
1)您将
$var
字符串作为literal与mkdir
一起使用,作为文件名glob与find
一起使用,以及作为extended regex与grep
一起使用。这些字符在每个上下文中可以有不同的含义。考虑到最终目标,可以丢弃
grep
,因此只需确保$var
在glob中使用时保持literal含义。下面是使用awk
进行全局转义的方法:第一个
**注意:**任意路径的唯一有效分隔符是
NUL
字节。嗯,这就是它的要点;没有理由为
$@
中的每个$var
触发一个awk
,因为您可以一次性执行所有全局转义,并在对$@
进行迭代时逐个读取它们:**2)**要查找名称中包含
$var_glob_safe
的文件,命令应为:但是,您希望用结果填充bash数组,因此必须告诉
find
使用NUL
字节分隔符(使用-print0
)并填充数组,如下所示:现在,您可以使用
${#files[@]}
访问“文件”的总数,因此您可以将逻辑建立在此基础上。**3)**下面的代码包含了上述解释和更多内容;唯一缺少的部分是
echo
s: