【问题标题】:Bash Script to find the Duplicate filenames in the same directory and send a Notification email用于在同一目录中查找重复文件名并发送通知电子邮件的 Bash 脚本
【发布时间】:2020-03-03 23:37:41
【问题描述】:

我的目标是通过比较同一目录中的所有文件名(abc.xyz,def.csv)来查找任何重复的文件名。如果没有任何重复的文件名,则将上述文件路径中的所有这些文件(.csv、.xlsx)移动到存档路径中。

如果存在重复文件名,则仅获取这些重复文件名的名称及其修改日期时间戳,并向团队发送通知电子邮件,并将剩余的非重复文件名移至存档文件夹。

如您所见,我正在尝试通过以下代码来实现它。

如果 find 命令为空,则执行 if 条件并执行 'mv' 命令并完全退出脚本,如果它们是重复文件,则退出 if 条件并管道重复文件并执行邮件和日期戳操作。

但是代码实际上在做什么,如果找到或没有找到任何重复文件,则发送通知电子邮件。

如果有重复文件,则发送包含重复文件名和修改名的电子邮件,如果没有重复文件名,则发送文件名为空白,当前时间为修改时间。

目前存档外没有文件(只有存档内的文件,但存档内的所有文件都是唯一的并且看起来不错),因此从技术上讲它不应该发送任何通知电子邮件。

{
DATE=`date +"%Y-%m-%d"`
dirname=/marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation
tempfile=myTempfileName
find $dirname -type f  > $tempfile
cat $tempfile | sed 's_.*/__' | sort |  uniq -d|
while read fileName
do
 grep "$fileName" $tempfile
done
}
if ["$fileName" == ""]; then
         mv /marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation/*.xlsx /marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation/Archive

         mv /marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation/*.csv /marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation/Archive
        exit 1

fi | tee '/marketsource/scripts/tj_var.txt' | awk -F"/" '{print $NF}'  | tee '/marketsource/scripts/tj_var.txt' | sort -u | tee '/marketsource/scripts/tj_mail.txt'



DATE=`date +"%Y-%m-%d"`
printf "%s\n" "$(</marketsource/scripts/tj_mail.txt)" | while IFS= read -r filename; do
   mtime=$(stat -c %y "/marketsource/SrcFiles/Target_Shellscript_Autodownload/Airtime_Activation/$filename")
   printf  'Duplicate Filename - %s Uploaded time - %s\n\n' "$filename" "$mtime"
done | mail -s "Duplicate file found ${DATE}" ti@gmail.com

【问题讨论】:

  • 你好@Bodo 请在上面找到我的问题。
  • 在同一个目录下不可能有两个同名的文件。
  • 将您的脚本粘贴到shellcheck.net 并修复它告诉您的所有内容。我相信还有一些关于管道如何工作的基本误解。
  • 抱歉我的错......它的 .xlsx 和 .csv 扩展名
  • 对我来说,仍然不清楚你在问什么。你没有描述你期望发生的事情和实际发生的事情;你应该尽可能地缩短你的脚本,同时保留相关的行为(见minimal reproducible example)。

标签: linux bash shell


【解决方案1】:

通过比较同一目录中的所有文件名(abc.xyz、def.csv)来查找任何重复的文件名。

它的 .xlsx 和 .csv 扩展名

我假设文件名中没有空格

IFS=$'\n'

duplicates=($(
       find . -maxdepth 1 -type f '(' -name '*.xlsx' -o -name '*.csv' ')' \
           -exec bash -c 'printf "%s %s\n" "$1" "${1%.*}"' -- {} \; |
       sort -k1 |
       uniq -f1 -d |
       cut -d' ' -f2
))
# or simpler:
duplicates=($(
    find . -type f '(' -name '*.xlsx' -o -name '*.csv' ')' |
    sed 's/\.[^\.]*$//' |
    sort |
    uniq -d
))

IFS=$' \t\n'

#如果没有任何重复的文件名,则将上述文件路径中的所有文件(.csv,.xlsx)移动到存档路径中

if ((${#duplicates[@]} == 0)); then
    find . -type f '(' -name '*.xlsx' -o -name '*.csv' ')' \
         -exec mv -v {} "$the_archive_path" \;

#如果有重复的文件名,那么

else

# 仅获取那些重复文件名的名称及其修改日期时间戳

    duplicate_filenames_with_modified_date=$(
       {
          printf "%s.xlsx\n" "${duplicates[@]}"
          printf "%s.csv\n" "${duplicates[@]}"
       } |
       xargs -d$'\n' stat -c '%n %y\n'
    )

#并向团队发送通知电子邮件并

    mail the_team <<<"a notification email"

# 将剩余的非重复文件名移动到存档文件夹。

    find . -maxdepth 1 -type f '(' -name '*.xlsx' -o -name '*.csv' ')' \
           -exec bash -c 'echo "$1" "${1%.*}"' -- {} \; | tee /dev/stderr |
       sort -k2 |
       uniq -f1 -u |
       cut -d' ' -f1 |
       xargs -r -d$'\n' -I{} echo mv -v {} "$the_archive_folder"
fi

【讨论】:

  • 使用换行符分隔的流来包含文件名列表通常是不安全的——众所周知。
  • @KamilCuk 感谢您的回复。所以我在存档之外创建了一个虚拟文件名并执行了脚本,它什么也没做,也没有给我发送任何通知电子邮件。请检查一下。我已经修改了邮件部分 duplicate_filenames_with_modified_date=$( { printf "%s.xlsx\n" "${duplicates[@]}" printf "%s.csv\n" "${duplicates[@]}" } | xargs -d$'\n' stat -c '%n %y\n' ) | mail -s "发现重复文件 ${DATE}" tli@aloup.com
  • 你不能做a=$(cmd1) | cmd2。使用command substitution 分配变量不会输出任何内容,因此使用| 管道重定向它会导致第二个命令接收到空输入。要么删除赋值和替换,要么真的只使用结果变量。对于电子邮件写作,我只会使用here document
  • 你好@kamilcuk,我指的是你的脚本。我已经执行了你的脚本,但似乎什么也没发生,关于电子邮件,是的,我会检查的。谢谢
猜你喜欢
  • 2014-02-18
  • 2017-05-06
  • 2014-12-23
  • 2020-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多