Bash:如果名称包含字符串列表之一,则将文件移动到特定文件夹

Bash: Move files to specific folder if name contains one of a list of strings

我有一个脚本可以在 Twitter API 中查询多个查询,然后将原始数据写入一个文件,文件中包含查询名称和时间戳。我想要一个脚本,给定查询字符串列表(正则表达式?)和文件夹中的所有文件,如果其中一个查询字符串是该文件中的子字符串,则将其移动到特定文件夹。现在我只有一个脚本,只有几十个 mv 命令,但我想要一个更简单、更易于维护的版本。这是我现在正在做的一个例子:

mv /home/nick/TwitterSearchToDatabase/queries_for_amita/*femin*/home/nick/TwitterSearchToDatabase/queries_for_amita/feminism
mv /home/nick/TwitterSearchToDatabase/queries_for_amita/*patriarchy* /home/nick/TwitterSearchToDatabase/queries_for_amita/feminism
mv /home/nick/TwitterSearchToDatabase/queries_for_amita/*yesallwomen* /home/nick/TwitterSearchToDatabase/queries_for_amita/feminism
mv /home/nick/TwitterSearchToDatabase/queries_for_amita/*womanpower* /home/nick/TwitterSearchToDatabase/queries_for_amita/feminism

我会使用 for 循环:

for i in femin patriarchy yesallwomen womanpower; do
  mv /home/nick/TwitterSearchToDatabase/queries_for_amita/*$i* /home/nick/TwitterSearchToDatabase/queries_for_amita/feminism
done

这样列表在第一行,方便修改。

我会隔离数据(要移到女权主义的话)和代码。 当你有更多的关键字(女权主义等)时,你可以制作带有关键字的文件并检查这些关键字文件是否有你正在考虑移动的文件。 使用 ${fromdir} 文件的来源,${todir} 您想要的文件和带有关键字的 ${keyfiledir},您会得到类似

for keyfile in ${keyfiledir}/*; do
   key="${keyfile##*/}"
   find $from -type f | sed 's#.*/##' | while read -r file; do
      echo "${file}" | grep -q -f "${keyfiledir}"/"${key}" && mv "${from}"/"${file}" "${to}"/"${key}"
   done
done

这是如何运作的?我用下面的脚本测试了上面的解决方案。

from=fromdir
to=todir
keyfiledir=keyfiledir
rm -rf ${from} ${to} ${keyfiledir}
mkdir ${from} ${to} ${keyfiledir}
mkdir ${to}/feminism ${to}/so
touch ${from}/yesallwomen ${from}/women ${from}/some_femin ${from}/"help move"
cat <<@ > ${keyfiledir}/feminism
femin
patriarchy
yesallwomen
womanpower
@
touch ${from}/yesallwomen ${from}/women ${from}/some_femin

cat <<@ > ${keyfiledir}/so
stack
exchange
help
@

test ! -d "${from}" && echo " Wrong dir ${from}" && exit 1
test ! -d "${to}" && echo " Wrong dir ${to}" && exit 1
test ! -d "${keyfiledir}" && echo " Wrong dir ${keyfiledir}" && exit 1

for keyfile in ${keyfiledir}/*; do
   key="${keyfile##*/}"
   find $from -type f | sed 's#.*/##' | while read -r file; do
      echo "${file}" | grep -q -f "${keyfiledir}"/"${key}" && mv "${from}"/"${file}" "${to}"/"${key}"
   done
done

echo "Not moved"
ls ${from}
echo "Moved"
ls -R ${to}

mvegrep 的简单组合就足够了。 egrep 可以从文件中获取模式列表(然后您可以使用完整的正则表达式语法,而不仅仅是 glob 语法。)确保排除目标文件夹的名称。

cd /home/nick/TwitterSearchToDatabase/queries_for_amita
mv $(ls | egrep -f patterns.txt | grep -v '^feminism$') feminism