下面是我的shell脚本。 我需要获取第二个最新的文件大小。 但是当我尝试在脚本下面运行时,我遇到了空间在哪里的问题,它试图将其作为目录/文件打开并给出没有此类文件或目录的错误。
请参阅以下错误。
tokenFileSubstring="/tmp/Anusha/exception_reports/ALIQD022_Active_Facilities with Pending_Fees_*.xls"
newFile=$(echo $tokenFileSubstring | sed "s/ /\ /g")
echo "newfile :: $newFile"
previousFileSize=`ls -lrt $newFile |tail -2 | head -1|awk '{print $5}'`
echo "previous file siz: $previousFileSize"
bash-4.1$ ./basic.sh
newfile ::/tmp/Anusha/exception_reports/AHJ800_Active_Facilities\ with\ Pending_Fees_2019-12-19-22-45-18.xls ls:无法访问/tmp/Anusha/exception_reports/ALIQD022_Active_Facilities:没有这样的文件或目录 ls:无法访问:没有这样的文件或目录 :没有这样的文件或directoryees_2019-12-19-22-45-18.xls
请帮我找到第二个最新的文件大小
如果你有GNU工具,并且你的shell是bash:
#!/usr/bin/env bash
[ -n "$BASH_VERSION" ] || { echo "This script requires bash" >&2; exit 1; }
dir=/tmp/Anusha/exception_reports
pattern='ALIQD022_Active_Facilities with Pending_Fees_*.xls'
{
read -d '' _; # ignore very latest file entirely
IFS= read -r -d ' ' time
IFS= read -r -d ' ' size
IFS= read -r -d '' name
} < <(find "$dir" -maxdepth 1 -type f -name "$pattern" -printf '%T@ %s %P ' | sort -zrg)
# note that this %()T timestamp formatting operator requires a quite new bash release.
printf 'Second latest file has name %q, size %d, time %(%Y-%m-%d %H:%M:%S)Tn'
"$name" "$size" "${time%%.*}"
其工作原理如下:
find -printf '%T@ %s %P '
,对于每个文件,发出以下内容:- 自纪元(即自 1970 年以来(以来的时间戳(以秒为单位(,后跟一个空格
- 该文件的大小(您要查找的内容(,后跟一个空格
- 文件的名称,后跟 NUL 字符。
这种格式很重要,因为时间戳和大小不能包含空格(因此空格可以安全地分隔它们(——但名称可以包含空格——此外,名称甚至可以包含换行符文字!因此,唯一可以安全用于查找文件名结尾的字符是 NUL,即 UNIX 路径中不可能存在的字符。sort -zrg
对由 NUL 分隔的记录(将时间戳视为数字 --g
支持浮点,而-n
只考虑整数部分(,对由 NUL 分隔的记录(这是-z
指定的(。-r
以相反的顺序排列,因此最新的文件排在第一位,而第二个最新的文件(您尝试查找的文件(排在第二位。<(...)
是一个进程替换,它扩展为输出为...
的文件名 - 在本例中为find | sort
管道的输出。从该进程替换重定向到前面的另一个<
意味着代码块(read
s(中的内容将看到进程替换的输出,而不会对使用管道创建的变量范围进行不必要的限制。read -d '' _
读取下一个 NUL,将结果放入虚拟变量_
(向读者暗示我们不打算读取或使用这些结果(。因此,将其作为处理流的第一项会忽略最新文件。IFS= read -r -d ' ' time
将所有内容读入变量time
的下一个空格。IFS= read -r -d ' ' size
将所有内容读入变量size
之后的空间。IFS= read -r -d '' name
将所有内容读取到变量name
中,直到下一个 NUL 。
。因此,我们能够将最新文件的名称、大小和时间戳收集到单独的变量中,而无需依赖非常不可靠的ls
工具。
使用这个答案,我们可以构建另一种方法。如果您认为您需要的文件总是以.xls
结尾,我们可以将文件名的开头存储在tokenFileSubstring
中,并且仅在ls
时使用扩展。
tokenFileSubstring="/tmp/Anusha/exception_reports/ALIQD022_Active_Facilities with Pending_Fees_"
previousFileSize=$(ls -lrt "$tokenFileSubstring"*.xls |tail -2 | head -1|awk '{print $5}')
echo "previous file siz: $previousFileSize"
另外,我不明白你想检索什么ls | tail | head | awk
.也许您只需ls | awk
就可以达到相同的结果
编辑
您也可以使用以下命令,只需ls | awk
,以简化:
previousFileSize=$(ls -lrt "$tokenFileSubstring"*.xls | awk 'BEGIN { n = 1 } { a[n++] = $5 } END { print a[n - 2] }'