다음과 같은 파일이 있습니다.
###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
매우 정교한 접근 방식을 취하고 있습니다. 쉘 스크립트가 필요하지 않습니다. 다음은 awk
한 줄의 코드입니다.
awk '{if(gsub(/#+/,"")){name=$0;}else{print > name".txt"}}' file
이것이 gsub
"전역 교체"입니다. 따라서 위의 의미는 "행에 가 있는 경우 #
해당 행을 삭제하고(아무 것도 대체하지 않음) 변수 "name"을 해당 행의 내용으로 설정합니다"를 의미합니다. 이제 해당 줄 #
은 삭제 후 남은 내용이 되므로 name
패턴이 됩니다. 그런 다음 행이 a와 일치하지 않으면 #
(대체가 실패하는 경우) 해당 행은 name
a라는 파일과 현재 값 으로 인쇄됩니다 .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