첫 번째 열을 기준으로 여러 Unix 파일을 여러 파일로 분할

첫 번째 열을 기준으로 여러 Unix 파일을 여러 파일로 분할

여러 파일(*data.txt)이 있고 열 1의 내용을 기준으로 각 파일을 여러 파일로 분할하려고 합니다. 나는 그것들을 분할했지만 $filename사용할 출력 파일의 열 1($1)을 사용하고 이름을 지정하는 방법을 모릅니다 print. 현재 다음 명령의 인쇄는 $1 ".txt"다음과 같은 내용을 제공합니다. 대신 ENSG00000115232.txt file1_ENSG00000108094.txt, file1_ENSG00000115232.txt는 각 입력 파일에 대해 별도의 출력이 필요하므로 부적절합니다. 내 명령은 다음과 같습니다. "$b"예상 결과를 얻으려면 이 명령을 어디에 사용해야 할지 잘 모르겠습니다 .

for filename in *_data.txt
 do
    b=${filename%%_data.txt}
cat $filename | awk 'NR==1 {header = $0; next}!header_printed[$1]++ {print header > $1".txt"}{print > $1".txt"}'
done

감사해요.

답변1

쉘 변수를 awk 프로그램에 전달하는 방법에는 여러 가지가 있습니다:

  1. -v명령줄 옵션을 사용합니다 .

    awk -v b=${filename%data.txt} '... {print > (b $1 ".txt")}'
    
  2. awk 프로그램 후에 일반 매개변수로 값을 전달합니다.

    awk '... {print > (b $1 ".txt")}' b=${filename%data.txt}
    
  3. 값을 전달하세요.환경내부 배열을 통해 ENVIRONawk로 액세스합니다.

    b=${filename%data.txt} awk '... {print > (ENVIRON["b"] $1 ".txt")}'
    

그러나 "몇 개의" 파일만 있는 경우 쉘 루프를 완전히 생략하고 모든 와일드카드 파일을 awk에 직접 전달하는 것이 합리적일 수 있습니다. 여기서 FILENAME출력 파일 접두사를 내부 변수에서 내보낼 수 있습니다. 예:

awk '
  FNR==1 {header = $0; b = FILENAME; sub(/data.txt$/,"",b); next}
  !header_printed[b $1]++ {print header > (b $1 ".txt")}
  {print > (b $1 ".txt")}
' *_data.txt

( 접미사를 사용 split하거나 substr제거 할 수도 있습니다 . 쉘 확장 에 가장 가까운 정규식을 사용했습니다 .)data.txtsub${filename%data.txt}

관련 정보