パターン検索に基づいてファイルを分割します。検索したパターンを使用したファイル名の分割

パターン検索に基づいてファイルを分割します。検索したパターンを使用したファイル名の分割

次のファイルがあります。

###PSTERS###
LINE1
LINE2
###PSTADS###
LINE3
LINE4
###PSTEEE###
LINE5
LINE6

3つのファイルを作成する必要があります(ファイル名は私たちが検索するパターンです)。

PSTERS.txt:

LINE1
LINE2

PSTADS.txt:

LINE3
LINE4

PSTEEE.txt:

LINE5
LINE6

どうすればいいですか?次のスクリプトを試しましたが、awk構文エラーのため失敗しました。

#!/bin/bash
#This script will take 2 parameters as input.
# 1. Source File Path
# 2. Source File name as input

SOURCE_PATH=$1
SOURCE_FILE=$2

#Get the list of patterns we need to check from the Main source file

cd $SOURCE_PATH
pattern_list=`grep -e '^\#' $SOURCE_FILE | cut -d'#' -f4`
echo ${pattern_list}

#Split the Source File for each pattern in the variable pattern_list

for pattern in ${pattern_list}
do
        cd $SOURCE_PATH
        awk '/\#\#\#'$pattern'/{x='$pattern';next}{print > x;}' $SOURCE_FILE
done

答え1

非常に洗練されたアプローチを取っています。シェルスクリプトは必要ありません。以下はawk1行のコードです。

awk '{if(gsub(/#+/,"")){name=$0;}else{print > name".txt"}}' file

これがgsub「グローバル交換」です。したがって、上記の意味は、「行に行っている場合は#その行を削除し(何も置き換えません)、変数「name」をその行の内容に設定します」を意味します。これで、その行#は削除後に残りの内容になるため、nameパターンになります。その後、行がaと一致しない場合#(代替が失敗した場合)、その行はnameaというファイルと現在の値で印刷されます.txt

それでもスクリプトをラップする必要がある場合は、次を使用してください。

#!/bin/bash -
#This script will take 1 parameter as input: the target file path
targetFile="$1"        
targetDir=$(dirname -- "$targetFile")
targetFile=$(basename -- "$targetFile")
cd -P -- "$targetDir" || exit
awk '{if(gsub(/#+/,"")){name=$0;}else{print > name".txt"}}' < "$targetFile"

答え2

我々はrelative addressingエディタを使用してedこれを行うことができます。

#これには、最初のステップで入力ファイル内のすべての行の行番号を抽出することが含まれます。その後、edタスクを完了するための一連のコマンドを生成します。右側はsed叙事詩が形象化した絵画空間の内容を示す。

sed -e '$s/.*/$/;$q;/^#/!d;=' inputfile |
sed -e '
   N;N;h;                            # p.s.:  1\n###PSTERS###\n4$

   s/^[1-9][0-9]*/&+/; /\$$/!s/$/-/; # p.s.:  1+\n###PSTERS###\n4-$

   s/\n\(.*\)\n\(.*\)/,\2w \1.txt/; # p.s.:   1+,4-w ###PSTERS###.txt$

   s/#//gp;g;                       # p.s.:   1+,4-w PSTERS.txt

   s/.*\n/\n/; $!D; s/.*/q/
' |
ed -s - inputfile

関連情報