文字列として扱われるディレクトリのリストを含む変数を防ぐ方法

文字列として扱われるディレクトリのリストを含む変数を防ぐ方法
#!/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に組み込まれている関数を使用して入力ファイルとディレクトリを解析することの1つの利点は、外部プログラムの呼び出しを防ぎ、スクリプトの実行を高速化できることです。

David A. Wheelersの追加資料シェルのファイル名とパス名:正しく取得する方法この種の処理を安全で安全な方法で処理するための有用なアドバイスと多数の例があります。

答え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"

関連情報