디렉토리에 파일 세트가 있습니다. 각 파일에는 ---PUBG-xxxxx--
또는이라는 줄이 있습니다 ---PUBG-xxxxx, PUBG-yyyyy ----
. 다음은 grep 명령의 출력입니다.
grep "^--" FILE*.sql | grep "PUBG"
FILE1.sql:---PUBG-10901--
FILE2.sql:---PUBG-11617--
FILE3.sql:---PUBG-11625--
FILE4.sql:--PUBG-11724--
FILE5.sql:---PUBG-11720, PUBG-11406---
FILE6.sql:---PUBG-11403---
FILE7.sql:---PUBG-12021--
FILE8.sql:---PUBG-12207--
FILE9.sql:---PUBG-12270--
FILE10.sql:---PUBG-12552--
FILE11.sql:--- PUBG-14284--
FILE12.sql:--- PUBG-10908--
FILE13.sql:--- PUBG-15136---
FILE14.sql:--- PUBG-15163---
FILE15.sql:--- PUBG-15166---
FILE16.sql:-- PUBG-15059 --
FILE17.sql:-- PUBG-15252 --
PUBG와 해당 번호는 무작위로 지정됩니다. 나에게 필요한 것은 파일 이름과 관련 PUBG 값뿐이지 --
PUBG 및 해당 값의 앞뒤가 아닙니다. FILE5.sql:---PUBG-11720, PUBG-11406---
다음 과 같은 for 루프 세트를 작성했습니다.
for (i in `grep "^--" FILE*.sql | grep "PUBG"`)
do
FILE_NAME=`echo ${i} | awk -F ":" {'print $1'}`
PUBG_NO=`echo ${i} | awk -F "PUBG-" {'print "PUBG-" $2'}`
echo ${FILE_NAME}
echo ${PUBG_NO}
done
그러나 샘플 출력 PUBG_NO
은 PUBG-15166---
for FILE15.sql
및 PUBG-11720,
입니다 FILE5.sql
.
파일의 특정 FILE_NAME에 대한 모든 PUBG 값이 필요하며 FILE5.sql에 대한 .PUBG 값은 정확한 결과를 얻기 위해 이 루프를 개선하는 방법이 --
될 수 있습니다 .PUBG-11720, PUBG-11406
답변1
루프를 작성할 필요가 없습니다. 출력을 sed로 파이프할 수 있습니다. 내 시도는 다음과 같습니다.
grep "^--" FILE*.sql | grep "PUBG" | sed -E 's/--+\ ?//g'
이것은 줄 것이다
FILE1.sql:PUBG-10901
FILE2.sql:PUBG-11617
FILE3.sql:PUBG-11625
FILE4.sql:PUBG-11724
FILE5.sql:PUBG-11720, PUBG-11406
FILE6.sql:PUBG-11403
FILE7.sql:PUBG-12021
FILE8.sql:PUBG-12207
FILE9.sql:PUBG-12270
FILE10.sql:PUBG-12552
FILE11.sql:PUBG-14284
FILE12.sql:PUBG-10908
FILE13.sql:PUBG-15136
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059
FILE17.sql:PUBG-15252
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059
FILE17.sql:PUBG-15252
여기서는 다음 형식의 sed 대체 명령을 사용하고 있습니다.
's/regular expression/substition/flag'
명령을 더 자세히 분석하면 다음과 같습니다.
- 정규식 "--+\?"는 찾아서 선택하려는 패턴입니다. 이는 "-" 뒤에 하나 이상의 연속된 "-"가 오고 그 뒤에 0개 또는 1개의 ""가 오는 패턴 찾기로 읽을 수 있습니다. 이는 "--", "---" 및 "-"와 일치합니다. - " 출력에. 이러한 수량자를 인식하려면 sed의 -E 플래그가 필요합니다.다음은 ? 및 +와 같은 정규식 수량자를 검토하기 위한 빠른 참조입니다.
- 여기서는 교체공간을 비워두었습니다. 이는 발견된 패턴을 널로 대체하며 출력을 제거하는 효율적인 방법입니다.
- 플래그 "g"는 검색이 전역적임을 나타냅니다. 이것이 없으면 교체는 각 행의 첫 번째 일치에서만 발생합니다. g를 추가하면 모든 줄에 있는 패턴의 모든 인스턴스가 무엇이든 대체됩니다.
또한 이러한 개념을 초기 grep 명령에 적용하여 단일 검색만 수행할 수도 있습니다.
grep -E "^--+\ ?PUBG" FILE*.sql | sed -E 's/--+\ ?//g'
답변2
다음 AWK:
awk '
BEGIN { RS="[,\n]"; }
/PUBG-[0-9][0-9][0-9][0-9][0-9]/ { match($0,/PUBG-[0-9][0-9][0-9][0-9][0-9]/); print(FILENAME ":" substr($0,RSTART,RLENGTH)); }
' FILE*.sql
다음과 같은 결과가 출력됩니다:
FILE11.sql:PUBG-14284
FILE1.sql:PUBG-10901
FILE3.sql:PUBG-11625
FILE5.sql:PUBG-11720
FILE5.sql:PUBG-11406
다음 5개의 파일만 고려됩니다.
$ ls FILE*.sql
FILE11.sql FILE1.sql FILE3.sql FILE5.sql
답변3
awk -F, '/^--/ && /PUBG/ {
for (i=1; i<=NF; ++i) {
sub("^[- ]*", "", $i)
sub("[- ]*$", "", $i)
print FILENAME, $i
} }' FILE*.sql
그러면 원본 SQL 파일을 반복하고 파이프라인을 대체합니다.
이 코드는 string awk
으로 시작하고 이를 포함하는 모든 줄을 추출합니다 . 이러한 각 줄에 대해 쉼표로 구분된 항목을 반복하고 각 항목의 시작과 끝에서 대시와 공백 문자를 제거합니다. 트리밍 후 문자열이 있는 파일 이름 앞에 결과 문자열을 인쇄합니다 .--
PUBG
PUBG-NNNN