열 번호가 잘못된 제어 파일을 기반으로 열을 선택하는 방법은 무엇입니까?

열 번호가 잘못된 제어 파일을 기반으로 열을 선택하는 방법은 무엇입니까?

다음 제어 파일을 기반으로 소스 파일에서 파일을 동적으로 생성해야 합니다.

control_file.txt 
1,3,5,-1,8,-1,4

제어 파일에는 소스 파일에서 필요한 열의 위치가 포함되어 있습니다.

예: 1개 열, 3개 열, 5개 열, 빈 열(-1은 빈 열을 의미) 등

제어 파일에서 위치를 하나씩 읽어 여러 파일을 생성하는 쉘을 작성했습니다. 그런 다음 -1 값으로 터치 파일을 생성하는 경우 마지막으로 붙여넣기 명령을 사용하여 새 파일을 생성합니다. 파일 순서에 따라 옵션을 통해 붙여넣습니다 ls-v.

따라서 내 기존 쉘은 다음과 같습니다.

if [ position != -1 ]
then
cut -d, -f$position > file_$var.csv 
else
touch file_$var.csv
fi
paste -d, $(ls -v file_*.csv) > newe_file.csv

파일에 대한 I/O를 최소화하는 방법이 있기를 바라며 다음을 찾고 있습니다.

cut -d, -f1,3,5 > file1.csv
touch file2.csv
cut -d, -f8 > file3.csv
touch file4.csv
cut -d, -f4 > file5.csv

아니면 더 나은 솔루션이 좋을 것입니다.

소스 파일의 열 수는 수백 개의 열이 됩니다.

예상 결과:

input-file is sample.csv

col1,col2,col3,col4,col5,col6,col7,col8
1,2,3,4,5,6,7,8
9,10,11,12,13,14,15,16

출력.csv:

col1,col3,col5,-1,col8,-1,col4
1,3,5,,8,,4
9,11,13,,16,,12

.csv 기반 출력controlfile.txt

답변1

다른 답변보다 조금 더 간단한 또 ​​다른 답변은 다음과 같습니다.

#!/bin/bash
fields=$(sed -r -e 's/-1/ /g' -e 's/,/ FS /g' \
  -e 's/([0-9]+)/\$\1/g' control_file.txt)
awk -F, "{print ${fields}}" $1

control_file.txt첫 번째 명령은 적절한 명령으로 변환됩니다 awk.

$1 FS $3 FS $5 FS FS $8 FS FS $4

실행하세요:

$ ./script.sh input.csv
col1,col3,col5,,col8,,col4
1,3,5,,8,,4
9,11,13,,16,,12

다른 샘플에서:

$ ./script.sh sample.csv
BP ID,CurrentMonetary balance ,Provider contract id,,End Date,,charge Plan names 
1100001538,251,00000000000000000141,,18-Oct-12,,[B2] R2 LTE CHARGE PLAN 
1100003404,45.22,00000000000000009349,,23-Nov-13,,B0.3 ECS_CHARGE_PLAN DROP1 V3

답변2

awk 파일

BEGIN { sp="-1" ;  FS="," ; }
FILENAME == "control.txt" { for (i=1;i<=NF;i++) col[i]=$i ;  next ;}
FILENAME != "control.txt" {
    comma="" ;
    for (i=1;i<NF;i++) {
            c=col[i] ;
            if (col[i]!=-1) printf "%s%s",comma,$c ;
            else printf "%s%s",comma,sp ;
            comma="," ;
    }
    printf "\n" ;
    sp="" ;
    }

달리다

 awk -f a.awk control.txt  sample.txt
 col1,col3,col5,-1,col8,-1,col4
 1,3,5,,8,,4
 9,11,13,,16,,12

기본적으로 control.txt의 첫 번째 줄은 인쇄할 열을 가져옵니다.

답변3

echo '1,2,3,4,5,6,7,8' |
sed 's/[^,]*//7;s///6;s///2;s/,,/,/
    s/\([^,]*\),\([^,]*\),,.*,\(.*\)/\2,,\3,,\1/'

이렇게 하면 필드 7, 6, 2의 내용이 삭제됩니다. 다음으로 첫 번째 빈 필드를 제거합니다. 그런 다음 2,,3,,1과 같이 비어 있지 않은 마지막 세 개의 필드를 바꿉니다.

산출

1,3,5,,8,,4

샘플 데이터를 실행합니다.

BP ID,CurrentMonetary balance ,Provider contract id,,End Date,,charge Plan names 
1100001538,251,00000000000000000141,,18-Oct-12,,[B2] R2 LTE CHARGE PLAN 
1100003404,45.22,00000000000000009349,,23-Nov-13,,B0.3 ECS_CHARGE_PLAN DROP1 V3

그런 다음 다시 구분 기호를 확인할 수 있는 한 다음을 수행할 수 있습니다.할 수 있는그냥 쉘을 사용하세요:

set -f; IFS=,
set -- $(cat file; echo "$IFS")
while [ $# -gt 8 ]
do printf %s\\n "$1,$3,$5,,$8,,$4"
   shift "$(($#>7?8:$#))"
done

셸 옵션을 사용하면 필드에 구분 기호를 제외한 모든 항목이 포함될 수 있습니다. 구분 기호가 있는 한 <space><tab><newline>빈 필드 이외의 필드는 유지됩니다. 세 개의 공백 문자를 포함하여 포함된 모든 문자는 유지됩니다. 여기서는 쉼표를 사용했습니다. 파일을 보관할 만큼 충분한 메모리가 필요합니다.

관련 정보