Bash 如何避免列出不存在的文件时出错?
我在文件名中按日期对文件进行分组,并按组进行处理Bash 如何避免列出不存在的文件时出错?,bash,Bash,我在文件名中按日期对文件进行分组,并按组进行处理 for m in {01..12}; do for d in {01..31}; do f=`ls ./mydir/2018.${m}.${d}T*.jpg` # process files done done 但是,如果某些日期不存在文件,则代码会引发错误,例如 ls:无法访问“2018.01.20T*.jpg”:没有此类文件或目录 如何跳过缺少的日期?启用nullglob以便不匹配的通配符扩展为零。然后,您可以简单地
for m in {01..12}; do
for d in {01..31}; do
f=`ls ./mydir/2018.${m}.${d}T*.jpg`
# process files
done
done
但是,如果某些日期不存在文件,则代码会引发错误,例如
ls:无法访问“2018.01.20T*.jpg”:没有此类文件或目录
如何跳过缺少的日期?启用
nullglob
以便不匹配的通配符扩展为零。然后,您可以简单地对匹配的文件进行迭代
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
for f in ./mydir/2018.${m}.${d}T*.jpg; do
# process file
done
done
done
如果要同时使用所有文件名,请将它们存储在一个文件夹中。数组优于普通字符串,因为它们可以处理带有空格和其他特殊字符的文件名
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
files=(./mydir/2018.${m}.${d}T*.jpg)
# process files
echo "processing ${files[@]}..."
done
done
什么是最干净的方法来本地化shopt,以便在此块之后将nullglob恢复为其原始(未知)值 使用子shell:用括号围绕块。子shell创建一个子进程,确保更改不会泄漏到父进程中
(
shopt -s nullglob
...
)
无论何时更改shell选项,这样做都是礼貌的,而且它是
pushd
+popd
的优雅替代品。请注意,任何变量赋值都是子shell的局部赋值,因此在这里要小心。启用nullglob
以便不匹配的通配符扩展为零。然后,您可以简单地对匹配的文件进行迭代
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
for f in ./mydir/2018.${m}.${d}T*.jpg; do
# process file
done
done
done
如果要同时使用所有文件名,请将它们存储在一个文件夹中。数组优于普通字符串,因为它们可以处理带有空格和其他特殊字符的文件名
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
files=(./mydir/2018.${m}.${d}T*.jpg)
# process files
echo "processing ${files[@]}..."
done
done
什么是最干净的方法来本地化shopt,以便在此块之后将nullglob恢复为其原始(未知)值 使用子shell:用括号围绕块。子shell创建一个子进程,确保更改不会泄漏到父进程中
(
shopt -s nullglob
...
)
无论何时更改shell选项,这样做都是礼貌的,而且它是
pushd
+popd
的优雅替代品。请注意,任何变量赋值都是子shell的局部变量,因此在这里要小心。这里有另一种方法,使用find:
find ./mydir/ -type f -regextype sed -regex ".*2018\.[0-9]\{,2\}\.[0-9]\{,2\}T.*\.jpg.*" -exec echo "---{}" \;
假设如下:
$ ls -l mydir/
total 0
-rw-r--r-- 1 0 Jan 23 16:46 2018.01.20Thellowet.jpg
-rw-r--r-- 1 0 Jan 23 16:47 2018.04.24Thellowet.jpg
-rw-r--r-- 1 0 Jan 23 16:46 some_random_crap
-rw-r--r-- 1 0 Jan 23 16:46 wet
-rw-r--r-- 1 0 Jan 23 16:46 when
-rw-r--r-- 1 0 Jan 23 16:46 who
-rw-r--r-- 1 0 Jan 23 16:46 wtf
使用查找:
find ./mydir/ -type f -regextype sed -regex ".*2018\.[0-9]\{,2\}\.[0-9]\{,2\}T.*\.jpg.*" -exec echo "---{}" \;
给出(通过将--
附加到文件名来对数据进行次要处理):
注意:这也将返回具有2018.00.xy
或2018.xy.00
的文件,其中x和y可以是0到9之间的任意数字
Regex解释说:
*
:任何图案
[0-9]{,2}
:一个两位数的数字
\
用于转义特殊字符。这里是另一种方法,使用find:
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
files=(./mydir/2018.${m}.${d}T*.jpg)
# process files
echo "processing ${files[@]}..."
done
done
find ./mydir/ -type f -regextype sed -regex ".*2018\.[0-9]\{,2\}\.[0-9]\{,2\}T.*\.jpg.*" -exec echo "---{}" \;
假设如下:
$ ls -l mydir/
total 0
-rw-r--r-- 1 0 Jan 23 16:46 2018.01.20Thellowet.jpg
-rw-r--r-- 1 0 Jan 23 16:47 2018.04.24Thellowet.jpg
-rw-r--r-- 1 0 Jan 23 16:46 some_random_crap
-rw-r--r-- 1 0 Jan 23 16:46 wet
-rw-r--r-- 1 0 Jan 23 16:46 when
-rw-r--r-- 1 0 Jan 23 16:46 who
-rw-r--r-- 1 0 Jan 23 16:46 wtf
使用查找:
find ./mydir/ -type f -regextype sed -regex ".*2018\.[0-9]\{,2\}\.[0-9]\{,2\}T.*\.jpg.*" -exec echo "---{}" \;
给出(通过将--
附加到文件名来对数据进行次要处理):
注意:这也将返回具有2018.00.xy
或2018.xy.00
的文件,其中x和y可以是0到9之间的任意数字
Regex解释说:
*
:任何图案
[0-9]{,2}
:一个两位数的数字
\
用于转义特殊字符。错误消息被发送到stdout(fd#2),因此只需将stdout重定向到/dev/null
,例如:ls./mydir/2018.${m}.${d}T*.jpg 2>/dev/null
;另一种选择是在尝试ls
之前测试文件的存在性,但这会使通配符(*)变得有点混乱,因此最简单的方法(imo)是将stdout(fd#2)重定向到/dev/null
;我还假设无论进程文件包含什么,它都知道如何处理空的${f}
错误消息被发送到stdout(fd#2),所以只需将stdout重定向到/dev/null
,例如:ls./mydir/2018.${m}.${d}T*.jpg 2>/dev/null
;另一种选择是在尝试ls
之前测试文件的存在性,但这会使通配符(*)变得有点混乱,因此最简单的方法(imo)是将stdout(fd#2)重定向到/dev/null
;我还假设无论#进程文件
需要什么,它都知道如何处理空的${f}
什么是最干净的方法来本地化shopt,以便在这个块之后将nullglob恢复到它以前的值?什么是最干净的方法来本地化shopt,以便在这个块之后将nullglob恢复到它以前的值?
shopt -s nullglob
for m in {01..12}; do
for d in {01..31}; do
files=(./mydir/2018.${m}.${d}T*.jpg)
# process files
echo "processing ${files[@]}..."
done
done