데이터가 있는 경우 파일 이름을 얻는 방법

데이터가 있는 경우 파일 이름을 얻는 방법

내 입력 파일은 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는 _와 점 사이의 문자열을 인쇄합니다.

관련 정보