基于模式搜索分割文件。用我们搜索的模式分割文件名

基于模式搜索分割文件。用我们搜索的模式分割文件名

我有一个文件,如下所示:

###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

你正在采取一种非常复杂的方法。不需要 shell 脚本,这是awk一行代码:

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

gsub就是“全球替换”。因此,上面的意思是“如果一行有任何#,则删除它们(替换为空),并将变量“name”设置为该行的内容”。由于该行现在将是删除后剩下的所有内容#name因此将成为模式。然后,如果该行与 a 不匹配#(如果替换失败),则将该行打印到名称为name和的当前值的文件中.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

相关内容