我正在Linux机器上编写一个shell脚本,通过crontab运行,这意味着将所有早于当天的文件移动到新文件夹,然后tar和压缩整个文件夹。看起来像一个简单的任务但由于某种原因,我遇到了各种各样的障碍。我是新手,并且自学成才,所以任何帮助或重定向都会非常感激。
所有日志文件都在/home/tech/logs/
,所有pdf都在/home/tech/logs/pdf
所有文件都超过一天,如文件名所示(文件名不包括$CURRENT_DATE
)
所有文件必须为*.log
或*.pdf
(即如果文件不是日志或pdf文件,则不归档不包含$CURRENT_DATE
的文件。< / p>
所有日志文件名称均为home/tech/logs
,格式为NAME 00_20180510.log
,所有pdf文件位于“pdf”子目录(home/tech/logs/pdf
)中,格式为{{1} }(“20180510”将在文件创建时为0,0为任意数字)。我需要使用名称而不是文件元数据来创建日期,并且名称不包含当前日期的所有文件(pdf / log)都是“旧”。我也不能只移动名称中不包含NAME 00_20180510_00000000.pdf
的所有文件,因为它会带有任何非$CURRENT_DATE
或*.pdf
文件。
现在,脚本会为旧文件(*.log
)创建一个新文件夹,其中包含新的pdf子目录。然后,我想将旧日志移动到mkdir -p /home/tech/logs/$ARCHIVE_NAME/pdf
,并将所有旧pdf从原始pdf子目录移动到$ARCHIVE_NAME
。
$ARCHIVE_NAME/pdf
这没有奏效,因为它将find /home/tech/logs -maxdepth 1 -name ( "*[^$CURRENT_DATE].log" "*.log" ) -exec mv -t "$ARCHIVE_NAME" '{}' ';'
find /home/tech/logs/pdf -maxdepth 1 -name ( "*[^$CURRENT_DATE]*.pdf" "*.pdf" ) -exec mv -t "$ARCHIVE_NAME/pdf" '{}' ';'
中的数字视为要排除的数字列表而不是文字字符串。
我考虑过使用tar这样的排除选项:
$CURRENT_DATE
但是a)它不起作用,并且b)理论上它将包括所有不是tar -cvzPf "$ARCHIVE_NAME.tgz" --directory /home/tech/logs --exclude="$CURRENT_DATE" --no-unquote --recursion --remove-files --files-from="/home/tech/logs/"
或*.pdf
文件的文件,这将是一个问题。
我是否过于复杂?有没有更好的方法来解决这个问题?
答案 0 :(得分:-1)
我会使用bash的扩展glob功能来解决这个问题,它允许你否定一个模式:
#!/bin/bash
shopt -s extglob
mv /home/tech/logs/*!("$CURRENT_DATE")*.log "$ARCHIVE_NAME"
mv /home/tech/logs/pdf/*!("$CURRENT_DATE")*.pdf "$ARCHIVE_NAME"/pdf
启用extglob
后,!(pattern)
会扩展到与模式(或管道分隔模式列表)不匹配的所有内容。
使用find
也应该可以:
find /home/tech/logs -name '*.log' -not -name "*$CURRENT_DATE*" -exec mv -t "$ARCHIVE_NAME" {} +
答案 1 :(得分:-1)
在@ tom-fenech上构建答案,经过优化以避免许多mv
次调用:
find /home/tech/logs -maxdepth 1 -name '*.log' -not -name "*_${CURRENT_DATE?}.log" | \
xargs mv -t "${ARCHIVE_NAME?}"
一个有趣的功能,从处理文件到管道,是能够使用额外的工具(也就是grep :)过滤它们,这可以(可以说)变得更易读,即 - &gt;
find /home/tech/logs -maxdepth 1 -name '*.log' | fgrep -v "_${CURRENT_DATE?}" | \
xargs mv -t "${ARCHIVE_NAME?}"
然后类似于pdf
个, BTW ,只需替换mv
即可&#34;干运行&#34; echo mv
。
- jjo