shell 如何在grep命令执行后没有返回结果时移动文件

ozxc1zmp  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(225)

我想在grep命令后移动一个文件,但在执行脚本时,我注意到没有返回任何结果。不管怎样,我想将文件/s移动到另一个目录。
这就是我一直在做的事

for file in *.sup
do 
   grep -iq "$file" '' /desktop/list/varlogs.txt || mv "$file" /desktop/first;
done

但我得到这个错误:

mv: 0653-401 Cannot rename first /desktop/first/first

建议会很有帮助

vyswwuz2

vyswwuz21#

我不知道..."$file" '' /desktop...之间的两个单引号是什么意思。如果有了它们,grep也会在名为''的文件中查找$file,所以grep会在那里抛出grep: : No such file or directory错误。
还要注意添加-q--quiet标志的行为变化,因为它会影响grep的返回值,并将影响是否运行||的命令(有关更多信息,请参见man grep)。
我不知道你到底想做什么,但是你可以添加一些语句来帮助你弄清楚发生了什么。你可以用bash -x ./myscript.sh来运行你的脚本,以显示它运行时运行的所有内容,或者在脚本中的for循环之前添加set -x,在for循环之后添加set +x,以显示发生了什么。
我在脚本中添加了一些调试功能,并将thx 1 m11n1x更改为if/then语句,以显示正在发生的情况。请尝试此操作,看看是否可以找到出错的地方。

echo -e "============\nBEFORE:\n============"
echo -e "\n## The files in current dir '$(pwd)' are: ##\n$(ls)"
echo -e "\n## The files in '/desktop/first' are: ##\n$(ls /desktop/first)"

echo -e "\n## Looking for '.sup' files in '$(pwd)' ##"

for file in *.sup; do
  echo -e "\n## == look for '${file}' in '/desktop/list/varlogs.txt' == ##"

  # let's change this to an if/else
  # the || means try the left command for success, or try the right one
  # grep -iq "$file" '' /desktop/list/varlogs.txt || mv -v "$file" /desktop/first

  # based on `man grep`:  EXIT STATUS
  #   Normally the exit status is 0 if a line is selected,
  #   1 if no lines were selected, and 2 if an error occurred.
  #   However, if the -q or --quiet or --silent is used and a line
  #   is selected, the exit status is 0 even if an error occurred.

  # note that --ignore-case and --quiet are long versions of -i and -q/ -iq
  if grep --ignore-case --quiet "${file}" '' /desktop/list/varlogs.txt; then
    echo -e "\n'${file}' found in '/desktop/list/varlogs.txt'"
  else
    echo -e "\n'${file}' not found in '/desktop/list/varlogs.txt'"
    echo -e "\nmove '${file}' to '/desktop/first'"
    mv --verbose "${file}" /desktop/first
  fi
done

echo -e "\n============\nAFTER:\n============"
echo -e "\n## The files in current dir '$(pwd)' are: ##\n$(ls)"
echo -e "\n## The files in '/desktop/first' are: ##\n$(ls /desktop/first)"
  • ||表示尝试第一个命令,如果不成功(即不返回0),然后执行下一个命令。在您的示例中,您正在查找/desktop/list/varlogs.txt,以查看当前目录中的任何.sup文件是否与varlogs文件中的任何文件匹配,如果不匹配,则将其移动到/desktop/first/目录。如果找到匹配项,把它们留在当前目录中。(根据你当前的逻辑)
  • mv --verbose解释正在执行的操作
  • echo -e启用反斜杠转义的解释
  • set -x显示正在运行/调试的命令

请回应和澄清,如果有什么不同。我正试图提高的行列,以更有帮助,所以我会感谢评论,和upvotes,如果这是有帮助的。

ltqd579y

ltqd579y2#

建议避免重复扫描/desktop/list/varlogs.txt,并删除重复项:

mv $(grep -o -f <<<$(ls -1 *.sup) /desktop/list/varlogs.txt|sort|uniq) /desktop/first

建议测试以下说明中的步骤1.,以列出要移动的文件。

说明

第一章:
列出/desktop/list/varlogs.txt in a single scan中提到的ls -1 *.sup中选择的所有文件。
-o仅列出匹配的文件名。
<<<$(ls -1 *.sup)准备一个包含所有模式匹配字符串的临时重定向输入文件。
|sort|uniq然后,排序列表并删除重复项(我们只能移动文件一次)。
第二章
将步骤1中找到的所有文件移动到目录/desktop/first

相关问题