내 입력 파일은 file_1.txt
, file_2.txt
, file_3.txt
등 입니다. 이 파일에는 다음 데이터가 포함되어 있습니다
$ head log_file_reset_*.txt
==> file_1.txt <==
Test #1
data
Test #2
data
Test #3
Test #4
data
==> file_2.txt <==
Test #1
Test #2
data
Test #3
Test #4
data
==> file_3.txt <==
Test #1
data
Test #2
data
Test #3
Test #4
Test
지금 가지고 있는 코드는 입력 파일의 각 데이터 아래에 사용 가능한 데이터가 다음과 같은 경우에만 후속 일련 번호를 얻을 수 있습니다.Test
#!/bin/bash
#################################################################################################
CWD=$(pwd)
for j in {1..5}
do
sed -n '
/^Test #/ {
s///
=
p
}
$=
' file_$j.txt \
| paste - - \
| awk -F '\t' '
NR > 1 && $1 - prevLine > ($2 ? 2 : 0) {print prev}
{prevLine = $1; prev = $2}
' >> 1_val.txt
이 코드에서 얻은 출력은 다음 위치에 저장됩니다 1_val.txt
.
1_val.txt
1
2
4
2
4
1
2
나열된 데이터의 파일 이름(숫자만)을 가져와서 1_val.txt
이름이 다른 파일에 저장 되도록 코드를 수정하는 방법을 알 수 있습니까 2_val.txt
?
예상 출력:
2_val.txt
1
1
1
2
2
3
3
답변1
awk를 사용하면 sed가 필요하지 않습니다. 모든 Unix 시스템의 모든 쉘에서 awk를 사용하여 질문의 쉘 스크립트가 수행하는 작업을 실제로 수행하는 방법은 다음과 같습니다.
$ cat tst.awk
FNR==1 {
testId = ""
}
testId != "" {
if (NF) {
print testId
}
testId = ""
}
sub(/^Test #/,"") {
testId = $0
}
$ awk -f tst.awk file_*.txt
1
2
4
2
4
5
1
2
그런 다음 위의 내용을 1개의 출력 파일로 인쇄하고 파일 번호를 다른 출력 파일로 인쇄하려면 다음과 같이 조정하십시오.
$ cat tst.awk
FNR==1 {
testId = ""
split(FILENAME,f,/[_.]/)
fileId = f[2]
}
testId != "" {
if (NF) {
print testId > "1_val.txt"
print fileId > "2_val.txt"
}
testId = ""
}
sub(/^Test #/,"") {
testId = $0
}
$ awk -f tst.awk file_*.txt
$ head *_val.txt
==> 1_val.txt <==
1
2
4
2
4
5
1
2
==> 2_val.txt <==
1
1
1
2
2
2
3
3
OP의 다음 주석을 해결하기 위해 편집하십시오. 별도의 파일에 저장하지 않으려는 경우 쉘 스크립트에서 위의 awk 스크립트 인라인을 사용하는 방법은 다음과 같습니다.
$ cat tst.sh
#!/usr/bin/env bash
awk '
FNR==1 {
testId = ""
split(FILENAME,f,/[_.]/)
fileId = f[2]
}
testId != "" {
if (NF) {
print testId > "1_val.txt"
print fileId > "2_val.txt"
}
testId = ""
}
sub(/^Test #/,"") {
testId = $0
}
' "${@:--}"
그런 다음 쉘 스크립트를 호출할 수 있습니다.
$ ./tst.sh file_*.txt
답변2
GNU sed 가 있다면 다음과 같이 할 수 있습니다:
sed -nsE '
/#/N;/\n./F
s/.*#([0-9]+)\n.+/\1/w1_val.txt
' file_?*.txt |
sed '/\n/P;y/_./\n\n/;D' > 2_val.txt
head [12]_val.txt
==> 1_val.txt <==
1
2
4
2
4
1
2
==> 2_val.txt <==
1
1
1
2
2
3
3
행 분석:
- 빠른 인쇄 모드에는 관심이 없고 파일 이름에만 관심이 있으므로 자동 인쇄(-n) 옵션 없이 sed를 호출합니다.
- 별도의 스트림(-s) 옵션을 사용하여 sed를 호출합니다. 일반적으로 sed는 모든 파일을 하나의 스트림으로 처리합니다.
- 데이터 행에 # 문자가 포함될 수 없다고 가정하고 다음 행을 연결하여 비어 있지 않은지 확인합니다. 이 경우 F 명령을 사용하여 현재 파일 이름을 인쇄하십시오.
- 두 번째 sed는 _와 점 사이의 문자열을 인쇄합니다.