파일을 추출하여 다양한 파일을 생성하고 이름을 바꿉니다.

파일을 추출하여 다양한 파일을 생성하고 이름을 바꿉니다.

다음과 같은 CSV(첫 번째 열과 두 번째 열이 ","로 구분됨) 파일이 있습니다.

Column1,Column2
4e,info1
4t,info2
45t,info3
3,info4

Column1에서 가져온 파일 이름과 Column2에서 가져온 내용을 사용하여 각 줄에 하나씩 4개의 다른 파일을 가져오고 싶습니다.

내 예상 결과는 다음과 같습니다

파일 이름 1 =4e.smi

info1

파일 이름 2 =4t.smi

info2

파일 이름 3 =45t.smi

info3

파일 이름 4 =3.smi

info4

나는 두 개의 서로 다른 변수(첫 번째 열과 관련된 하나, 두 번째 열과 관련된 변수)를 생성하고 해당 변수를 사용하여 새 파일을 생성할 수 있다고 생각했습니다. 모든 행에 대해 루프에서 이 작업을 수행합니다. 하지만 이 명령줄을 시도했지만 작동하지 않습니다.

while IFS=',' read -r name smile; do write "$smile" "$name".smi; done < InputFIle.txt

누구든지 이 문제를 해결하도록 도와줄 수 있나요?

감사해요.

답변1

write이 명령이 사용하려는 명령이 아니라는 점을 제외하면 루프가 거의 정확합니다. 대신 printf리디렉션과 함께 사용하세요. 또한 초기 행을 건너뛰는지 확인해야 하며 다양한 방법으로 이를 수행할 수 있습니다. 아래에서는 을 사용하고 있지만 tail -n +2을 사용할 수도 있습니다 sed 1d.

tail -n +2 InputFIle.txt |
while IFS=, read -r name string; do
    printf '%s\n' "$string" >"$name".smi
done

이는 파일 이름이 한 번만 기록된다고 가정합니다. 두 개 이상의 행이 첫 번째 열에 동일한 값을 갖는 것처럼 후속 행으로 인해 파일에 이미 기록된 데이터를 덮어쓰게 됩니다. 그래서 >당신 은>>에 추가하다결과물 파일. 코드를 두 번 실행하려는 경우(그렇지 않으면 출력에 중복 데이터가 표시됨) 이 변경으로 인해 해당 파일을 추가로 삭제해야 합니다.

awk잠재적으로 더 효율적인 접근 방식은 다음과 같이 사용하는 것입니다.

awk -F, 'NR > 1 { print $2 >($1 ".smi") }' InputFIle.txt

그러면 두 번째 쉼표로 구분된 필드가 첫 번째 필드에 지정된 파일 이름으로 인쇄됩니다. NR1(지금까지 읽은 레코드 수)에 대해 테스트하여 첫 번째 행을 건너뜁니다 .

이는 쉘 루프와 동일한 문제를 겪지 않습니다. 출력 파일은 첫 번째 파일 이후 잘리고(비우거나 생성됨) print후속 출력이 추가됩니다.

일부 줄에 더 많은 필드가 있는 경우 awk첫 번째 필드를 제외한 모든 필드를 인쇄하도록 변형을 수정해야 합니다.

awk -F, 'NR > 1 { name = $1; sub("[^,]*,",""); print >(name ".smi") }' InputFIle.txt

이렇게 하면 첫 번째 필드가 별도의 변수에 저장되고 다음을 사용하여 name원래 행에서 필드가 제거됩니다. sub()그런 다음 나머지 줄을 파일에 인쇄합니다.

답변2

생성해야 하는 출력 파일 수에 관계없이 tail+sort+awk를 사용하면 효율적으로 작동합니다.

tail -n +2 file | sort | awk -F, '$1!=prev{close(out); out=$1".smi"; prev=$1} {print $2 > out}'

출력 파일을 항상 닫지 않으면 대부분의 awk에서 "열린 파일이 너무 많습니다" 오류가 발생하거나 GNU awk가 파일 열기/닫기를 관리하려고 시도하므로 속도가 크게 느려질 것입니다. 초과되면 20개 출력 파일의 임계값 미만으로 표시됩니다. 입력에서 중복된 $1을 볼 때마다 출력 파일을 열거나 닫을 필요가 없도록 먼저 정렬을 수행합니다.

관련 정보