다음 제어 파일을 기반으로 소스 파일에서 파일을 동적으로 생성해야 합니다.
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>
빈 필드 이외의 필드는 유지됩니다. 세 개의 공백 문자를 포함하여 포함된 모든 문자는 유지됩니다. 여기서는 쉼표를 사용했습니다. 파일을 보관할 만큼 충분한 메모리가 필요합니다.