파일 유형에 따라 한 줄씩 디렉토리의 파일 융합

파일 유형에 따라 한 줄씩 디렉토리의 파일 융합

save특정 디렉터리에서 동일한 유형의 파일을 융합하는 루프의 다른 함수에 의해 호출 되는 함수가 있습니다 for(각 파일의 내용을 기반으로 새 파일에 한 줄씩 복사하여 해당 유형으로 복사).

퓨전 파일의 이름은 ${x}_type_${y}.log다음과 같은 형식입니다. xy저장 함수를 호출하는 다른 함수의 변수이며, type은 파일의 유형입니다.

cat, echo및 를 사용하여 paste파일을 융합 해 보았지만 아무 것도 작동하지 않았습니다. 스크립트를 실행할 때 융합된 파일은 융합된 파일 유형을 기반으로 코드에 설정된 이름을 전달하지만 융합된 파일은 비어 있거나 내용 대신 융합되어야 하는 파일의 이름을 포함합니다.

for file in *;
do
type=$( echo "$file" | awk -F'[.-]' '{print $2}' )
save () {
 if [[ "$type" == "$type1" ]];
  then
   cat "$file" >> "${x}_First_${y}.log"
 elif [[ "$type" == "$type2" ]];
  then
   cat "$file" >> "${x}_Second_${y}.log"
 elif [[ "$type" == "$type3" ]];
  then
   cat "$file" >> "${x}_Third_${y}.log"
elif [[ "$type" == "$type4" ]];
  then
   cat "$file" >> "${x}_Fourth_${y}.log"
 else
  echo "Nothing to do"
 fi
 }
done

또한 각 파일의 내용을 한 줄씩 새 파일에 복사해 보았지만 여전히 작동하지 않습니다.

for file in *;
do
type=$( echo "$file" | awk -F'[.-]' '{print $2}' )
save () {
  if [[ "$type" == "$type1" ]];
  then
      while IFS= read -r line
do
echo "$line"
echo -e "$line\n" >>"${x}_Request_${y}.log"

done <"$file"
  elif [[ "$type" == "$type2" ]];
  then
      while IFS= read -r line
do
echo "$line"
echo -e "$line\n" >>"${x}_Error_${y}.log"

done <"$file"
 elif [[ "$type" == "$type3" ]];
     then
      while IFS= read -r line
do
echo "$line"
echo -e "$line\n" >>"${x}_Critical_${y}.log"

done <"$file"
 elif [[ "$type" == "$type4" ]];
  then
 while IFS= read -r line
do
echo "$line"
echo -e "$line\n" >>"${x}_Test_${y}.log"

done <"filename"
 else
  echo "Nothing to do"
 fi
}
done

전체 스크립트입니다

#!/bin/bash

env1="dev"
env2="prod"
type1="request"
type2="error"
type3="critical"
type4="test"

save () {
 if [[ "$type" == "$type1" ]];
  then
   cat "$file" >> "${m}_Request_${w}.log"
 elif [[ "$type" == "$type2" ]];
  then
   cat "$file" >> "${m}_Error_${w}.log"
 elif [[ "$type" == "$type3" ]];
  then
   cat "$file" >> "${m}_Critical_${w}.log"
elif [[ "$type" == "$type4" ]];
  then
   cat "$file" >> "${m}_Test_${w}.log"
 else
  echo "Nothing to do"
 fi
 }

week_range () {
 if [[ "$day" -ge 1 && "$day" -le 7 ]];
   then
    w="Wk1"
    save
 elif [[ "$day" -ge 8 && "$day" -le 14 ]];
  then
    w="Wk2"
    save
 elif [[ "$day" -ge 15 && "$day" -le 21 ]];
  then
    w="Wk3"
save
 elif [[ "$day" -ge 22 && "$day" -le 28 ]];
  then
    w="Wk4"
    save
 elif [[ "$day" -ge 29 && "$day" -le 31 ]];
  then
    w="Wk5"
    save
 else
echo "Nothing to do"
fi
 }

month_range () {
 if [[ "$month" -eq 1 ]];
 then
   m="Jan"
   week_range
elif [[ "$month" -eq 2 ]];
then
   m="Feb"
   week_range
elif [[ "$month" -eq 3 ]];
 then
   m="Mar"
   week_range
elif [[ "$month" -eq 4 ]];
 then
   m="Apr"
week_range
elif [[ "$month" -eq 5 ]];
 then
   m="May"
   week_range
elif [[ "$month" -eq 6 ]];
 then
   m="Jun"
   week_range
elif [[ "$month" -eq 7 ]];
then
   m="Jul"
   week_range
elif [[ "$month" -eq 8 ]];
then
   m="Aug"
   week_range
elif [[ "$month" -eq 9 ]];
 then
   m="Sep"
week_range
elif [[ "$month" -eq 10 ]];
 then
  m="Oct"
  week_range
elif [[ "$month" -eq 11 ]];
 then
  m="Nov"
  week_range
elif [[ "$month" -eq 12 ]];
then
  m="Dec"
  week_range
else
   echo "Nothing to do"
fi
 }
for file in *.log;
do
env=$( echo "$file" | awk -F'[.-]' '{print $1}' )
type=$( echo "$file" | awk -F'[.-]' '{print $2}' )
month=$((10#$( echo "$file" | awk -F'[.-]' '{print $4}' )))
day=$((10#$( echo "$file" | awk -F'[.-]' '{print $5}' )))

if [[ "$env" == "$env1" ]];
then
    cd Env1 && { month_range; cd -; }
elif [[ "$env" == "$env2" ]];
  then
    cd Env2 && { month_range; cd -; }
else
  echo "Nothing to do"
fi
done

이것이 내 파일의 모습입니다

dev.critical-2021-01-05.log  prod.critical-2021-12-07.log
dev.critical-2021-08-09.log  prod.error-2021-02-21.log
dev.error-2021-08-01.log     prod.error-2021-07-29.log
dev.error-2021-08-07.log     prod.error-2021-10-22.log
dev.request-2021-08-01.log   prod.request-2021-01-02.log
dev.request-2021-08-12.log   prod.request-2021-04-10.log
dev.test-2021-09-03.log

이것이 내가 다른 디렉토리의 dev 및 prod에 대해 기대하는 것입니다.

Jan_Critical_Wk1.log         
Jan_Request_Wk1.log          
Jun_Request_Wk1.log  
Mar_Critical_Wk2.log        
May_Error_Wk2.log  
Feb_Error_Wk3.log      
Apr_Request_Wk2.log          
Aug_Critical_Wk1.log         
Aug_Critical_Wk2.log         
Aug_Error_Wk1.log            
Aug_Error_Wk2.log            
Aug_Request_Wk1.log          
Aug_Request_Wk2.log          
Nov_Error_Wk3.log
Oct_Error_Wk4.log
Sep_Request_Wk4.log
Jul_Error_Wk5.log            
Sep_Test_Wk1.log

답변1

cat파일을 사용할 수 없는 다른 디렉터리로 이동한 후 참조된 파일을 참조하려고 시도하는 중에 오류가 발생했습니다 .$file

파일 이름을 확인하고 그에 따라 분류하는 것 같습니다.

코드를 더 간단하게 만들 수 있습니다.

#!/bin/bash

shopt -s nullglob

declare -A envdir

months=( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )
envdir=( [dev]=Env1 [prod]=Env2 )

for name in *.log; do
        IFS='.-' read -r env type year month day suffix <<<"$name"

        m=${months[(10#$month) - 1]}
        w="Wk$(( 1 + (10#$day)/7 ))"

        if [ -z "$m" ] || [ ! -d "${envdir[$env]}" ]; then
                echo 'Nothing to do'
                continue
        fi

        cat -- "$name" >>"${envdir[$env]}/${m}_${type^}_$w.log"
done

위의 내용은 유형의 디렉토리 이름이 이미 파일 이름의 일부라는 사실을 사용합니다. 를 구현하는 데 사용하는 첫 문자만 대문자로 하면 됩니다 ${type^}. 읽기 변수는 파일 이름의 여러 부분에 사용됩니다 read.

if긴 목록을 반복하는 대신 then월 번호를 기반으로 배열에서 월 이름을 선택합니다 . else주 번호는 일을 기준으로 계산됩니다. 사용할 환경 디렉토리는 연관 배열에 저장됩니다 envdir.

cd우리는 아무데도 갈 필요가 없습니다 .

nullglob쉘 옵션을 사용하면 일치하는 항목이 없으면 와일드카드 패턴이 완전히 사라집니다. 그렇지 않은 경우 nullglob패턴이 *.log할당 name되고 적어도 한 번의 루프 반복이 발생합니다.

유효한 파일만 선택되도록 파일 이름을 선택하는 방법을 더욱 제한할 수도 있습니다.

#!/bin/bash

shopt -s nullglob extglob

declare -A envdir

months=( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )
envdir=( [dev]=Env1 [prod]=Env2 )

for name in @(dev|prod).@(critical|error)-????-??-??.log; do
        # as before
done

쉘 옵션이 추가 extglob되었습니다. 이를 통해 ksh우리가 보고 싶은 특정 이름과 일치하도록 확장과 유사한 와일드카드 패턴을 작성할 수 있습니다 . 특히, @(pattern|pattern|pattern)포함된 패턴이나 문자열 중 하나를 일치시킬 수 있습니다.

관련 정보