如何避免包含目录列表的变量被视为字符串

如何避免包含目录列表的变量被视为字符串
#!/bin/bash

Dir='/home/TEST'
Project="${Dir}/Project.txt"

文本文件Project.txt包含文件类型及其路径:

SOURCE|FILE|TARGET_PATH
TEST|BDL|/LOAN/NDL/XML
TEST|BDL|/LOAN/DL/XML
TEST|BDL|/LOC/DL/XML
TEST|ADU|/LOAN/NDL/XML
TEST|ADU|/LOAN/DL/XML
TEST|ADU|/LOC/DL/XML

通过修改我自己的问题和提供的答案,我将代码修改为:

while IFS='|' read -r source file path
do
    unset IFS

    if [ "${source}!" != "TEST!" ]
    then
        continue
    fi

    for dir in "${path}"; do
        find "${Dir}${dir}" -type f | grep ^'file' >"${Dir}${dir}"/"${file}"_Totallist.txt
    echo "${Dir}${dir}"
    done

done < "$Project"

回声结果:

/home/ds4078/TEST_XXX/LOAN/NDL/XML

/home/ds4078/TEST_XXX/LOAN/DL/XML

/home/ds4078/TEST_XXX/LOC/DL/XML

/home/ds4078/TEST_XXX/LOAN/NDL/XML

/home/ds4078/TEST_XXX/LOAN/DL/XML

/home/ds4078/TEST_XXX/LOC/DL/XML

"${file}"_Totallist.txt在各自的目录中成功创建,这意味着目录已成功通过。

现在的问题只是文本文件是空的,但是原来的问题已经解决了。也许是程序有问题ind "${Dir}${dir}" -type f | grep ^'file' >"${Dir}${dir}"/"${file}"_Totallist.txt

答案1

要单独处理每个目录,$path您需要迭代$path外循环中的条目:

    path=`grep "^TEST" ${Dir}/Project.txt | cut -d"|" -f3`

    for dir in $path; do
      for f in `ls -Rd "${Dir}${path}"/* -type f | grep ^${file}`; do
        ${f} >"${Dir}${path}"/"${file}"_total_file_list.txt
      done
    done

但是,由于处理循环似乎还引用了与$file从该条目读取的目录相匹配的文件名,因此您还需要$file以匹配的速度同时迭代。更直接的方法是单独处理每一行Project.txt

while read line; do
  IFS='|';
  fields=($line);  # split $line on '|' delimiters
  unset IFS;

  source=${fields[0]}
  file=${fields[1]}
  path=${fields[2]}

  if [ "$source!" != "TEST!" ]
  then
    continue  # skip lines not beginning with "TEST"
  fi

  for f in `ls -Rd "${Dir}${path}"/* -type f | grep ^${file}`
  do
    ${f} >> "${Dir}${path}"/"${file}"_total_file_list.txt
  done

done <Project.txt

这使用了 Bash 的输入字段分隔符在分隔符处分割输入文件中的每条记录|

最后,你不应该解析的输出ls。您可以使用 bash 中的内置模式匹配功能来迭代文件:

for f in "{Dir}${path}"/**/"$file"*; do
  if [ -f "${f}" ]  # check that $f is a file
  then
    ${f} >> "${Dir}${path}"/"${file}"_total_file_list.txt
  fi
done

使用 Bash 中的内置功能来解析输入文件和目录的一个优点是避免调用外部程序,这可能会导致更快的脚本执行。

进一步阅读 David A. Wheelers 的文章Shell 中的文件名和路径名:如何正确执行提供了有用的建议和大量示例,以安全可靠的方式处理此类处理。

答案2

使用双引号。 (检查最后一个命令的输出。)

例子

$ ls *.txt
test1.txt  test2.txt  test3.txt  test4.txt  test5.txt

$ files=$(ls *.txt)

$ echo ${files}
test1.txt test2.txt test3.txt test4.txt test5.txt

$ echo "${files}"
test1.txt
test2.txt
test3.txt
test4.txt
test5.txt

所以,在你的情况下,你需要像这样使用它

echo "${path}" | while read dir_path
do
       ls -r "${Dir}${dir_path}"
done

另外,您使用 grep 的 find 命令不正确。尝试使用 xargs

find path -type f | xargs grep "pattern"

相关内容