检查列表中的多个文件(不同路径)是否存在

检查列表中的多个文件(不同路径)是否存在

我有一个没有产生结果的作业脚本,我的怀疑之一是缺少一些名为的文件,作业脚本的相关部分如下所示:

  echo get_data

  get_fms_data \
    amip1 \
    seaesf \
    albedo \
    lad \
    topog \
    ggrpsst \
    mom4 \
    /data0/home/rslat/GFDL/archive/edg/fms/river_routes_gt74Sto61S=river_destination_field \
    /data0/home/rslat/GFDL/archive/fms/mom4/mom4p1/mom4p1a/mom4_ecosystem/preprocessing/rho0_profile.nc \
    /data0/home/rslat/GFDL/archive/fms/mom4/mom4p0/mom4p0c/mom4_test8/preprocessing/fe_dep_ginoux_gregg_om3_bc.nc=Soluble_Fe_Flux_PI.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/cover_type_1860_g_ens=cover_type_field \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/soil_color.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/biodata.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/ground_type.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/groundwater_residence.nc \
    /data0/home/rslat/GFDL/archive/ms2/esm2.1/input/max_water.nc \
...

第一步,我想将所有这些路径复制到一个文本文件中,然后检查它们是否确实存在。

有简单的方法吗?我查看了其他问题,但大多数问题都指仅检查一个文件而不是从文件中检查。

谢谢你!

答案1

这是一种方法(假设使用 GNU 工具):

grep -Po '^\s*\K/.*' file | 
    sed 's/\s*\\//'  | 
        while IFS= read -r path; do 
            [[ -e "$path" ]] && 
                printf 'FOUND: "%s"\n' "$path" || 
                printf "ERROR: '%s' doesn't exist\n" "$path"; 
        done 

解释

  • grep -Po '^\s*\K/.*':仅查找以 0 个或多个空白字符开头,然后是/.这将打印带有目标路径的行。
  • sed 's/\s*\\//':删除所有尾随空格和尾随反斜杠。
  • while IFS= read -r path; do:将每一行(路径)读入变量中$path
  • [[ -e "$path" ]] && printf 'FOUND: "%s"\n' "$path":如果该路径存在,则打印相关消息。
  • || printf "ERROR: '%s' doesn't exist\n" "$path";:否则,如果不存在,则打印错误消息。

答案2

我会用ls——不,不会解析 ls 的输出!,但使用其向 stderr 报告丢失文件的行为。输入三个字符“ ls”( l s Space),然后粘贴文件列表,然后输入> /dev/null。问题中文件名的示例:

ls  /data0/home/rslat/GFDL/archive/edg/fms/river_routes_gt74Sto61S=river_destination_field \
    /data0/home/rslat/GFDL/archive/fms/mom4/mom4p1/mom4p1a/mom4_ecosystem/preprocessing/rho0_profile.nc \
    /data0/home/rslat/GFDL/archive/fms/mom4/mom4p0/mom4p0c/mom4_test8/preprocessing/fe_dep_ginoux_gregg_om3_bc.nc=Soluble_Fe_Flux_PI.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/cover_type_1860_g_ens=cover_type_field \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/soil_color.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/biodata.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/ground_type.nc \
    /data0/home/rslat/GFDL/archive/jwd/regression_data/esm2.1/input/groundwater_residence.nc \
    /data0/home/rslat/GFDL/archive/ms2/esm2.1/input/max_water.nc \
  > /dev/null

如果每个文件都存在,您将不会得到任何输出;您将收到有关不存在的消息(因为我们允许 stderr 通过)。对于(虚构的)示例:

ls  /bogus/data0/home/rslat/GFDL/archive/edg/fms/river_routes_gt74Sto61S=river_destination_field \
    /bogus/data0/home/rslat/GFDL/archive/fms/mom4/mom4p1/mom4p1a/mom4_ecosystem/preprocessing/rho0_profile.nc
    > /dev/null

你会得到:

ls: cannot access /bogus/data0/home/rslat/GFDL/archive/edg/fms/river_routes_gt74Sto61S=river_destination_field: No such file or directory
ls: cannot access /bogus/data0/home/rslat/GFDL/archive/fms/mom4/mom4p1/mom4p1a/mom4_ecosystem/preprocessing/rho0_profile.nc: No such file or directory

这个方法也很容易编写脚本——只需检查返回代码(如果您愿意,可以删除 stderr):

if ls /data0/exists /bogus/doesnot > /dev/null 2> /dev/null
then
  echo all files exist
else
  echo some files are missing
fi

相关内容