문자열로 처리되는 디렉토리 목록을 포함하는 변수를 방지하는 방법

문자열로 처리되는 디렉토리 목록을 포함하는 변수를 방지하는 방법
#!/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의 추가 자료셸의 파일 이름과 경로 이름: 올바르게 얻는 방법이러한 유형의 처리를 안전하고 안전한 방식으로 처리하기 위한 유용한 조언과 수많은 예가 제공됩니다.

답변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"

관련 정보