ファイルの種類に応じて1行ずつディレクトリ内のファイルの融合

ファイルの種類に応じて1行ずつディレクトリ内のファイルの融合

save特定のディレクトリで同じタイプのファイルを融合するループの他の関数によって呼び出される関数がありますfor(各ファイルの内容に基づいて新しいファイルに1行ずつコピーしてそのタイプにコピー)。

フュージョンファイルの名前は${x}_type_${y}.log次の形式です。xおよびy保存関数を呼び出す他の関数の変数です。typeはファイルの種類です。

catechoおよびを使用して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

また、各ファイルの内容を1行ずつ新しいファイルにコピーしてみましたが、まだ機能しません。

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、少なくとも1回のループ反復が発生します。

有効なファイルのみを選択するようにファイル名を選択する方法をさらに制限することもできます。

#!/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)埋め込まれたパターンまたは文字列のいずれかを一致させることができます。

おすすめ記事