다음 파일이 있습니다.
id name age
1 ed 50
2 joe 70
id
나는 단지 인쇄 와 칼럼을 원합니다 age
. 이제는 다음을 사용합니다 awk
.
cat file.tsv | awk '{ print $1, $3 }'
그러나 이를 위해서는 열 번호를 알아야 합니다. 열 번호 대신 열 이름(첫 번째 줄에 지정)을 사용할 수 있는 방법이 있습니까?
답변1
어쩌면 다음과 같은 것일 수도 있습니다.
$ cat t.awk
NR==1 {
for (i=1; i<=NF; i++) {
ix[$i] = i
}
}
NR>1 {
print $ix[c1], $ix[c2]
}
$ awk -f t.awk c1=id c2=name input
1 ed
2 joe
$ awk -f t.awk c1=age c2=name input
50 ed
70 joe
명령줄에 인쇄할 열을 지정하려면 다음을 수행할 수 있습니다.
$ cat t.awk
BEGIN {
split(cols,out,",")
}
NR==1 {
for (i=1; i<=NF; i++)
ix[$i] = i
}
NR>1 {
for(i=1; i <= length(out); i++)
printf "%s%s", $ix[out[i]], OFS
print ""
}
$ awk -f t.awk -v cols=name,age,id,name,id input
ed 1 ed 50 1
joe 2 joe 70 2
( -v
블록에 정의된 변수를 가져오기 위한 스위치에 유의하세요 BEGIN
.)
답변2
csvkit
입력 데이터를 csv 형식으로 변환하고 csv 도구를 사용합니다.csvcut
에서 csvkit
:
$ cat test-cols.dat
id name age
1 ed 50
2 joe 70
csvkit을 설치합니다:
$ pip install csvkit
tr
squeeze 옵션과 함께 사용하여 -s
유효한 csv 파일로 변환하고 적용합니다 csvcut
.
$ cat test-cols.dat | tr -s ' ' ',' | csvcut -c id,age
id,age
1,50
2,70
이전 데이터 형식으로 되돌리려면 다음을 사용할 수 있습니다.tr ',' ' ' | column -t
$ cat test-cols.dat | tr -s ' ' ',' | csvcut -c id,age | tr ',' ' ' | column -t
id age
1 50
2 70
노트
csvkit은 또한 다양한 구분 기호(공유 옵션
-d
또는--delimiter
), 그러나 csv 파일을 반환합니다.파일이 열을 구분하기 위해 공백만 사용하는 경우(탭이 전혀 없음) 다음이 작동합니다.
$ csvcut -d ' ' -S -c 'id,age' test-cols.dat id,age 1,50 2,70
파일이 탭으로 구분된 열을 사용하는 경우 다음이 작동하고
csvformat
TSV 파일을 다시 가져오는 데 사용할 수 있습니다.$ csvcut -t -c 'id,age' test-cols.dat | csvformat -T id age 1 50 2 70
제가 확인해본 결과 탭은 하나만 허용됩니다.
csvlook
테이블은 Markdown 테이블 형식으로 포맷될 수 있습니다.$ csvcut -t -c "id,age" test-cols.dat | csvlook | id | age | | -- | --- | | 1 | 50 | | 2 | 70 |
UUOC(쓸모없는 고양이): 나는 이런 식으로 명령을 구성하는 것을 좋아합니다.
답변3
그냥 Perl 솔루션을 더미 위에 던져보세요:
#!/usr/bin/perl -wnla
BEGIN {
@f = ('id', 'age'); # field names to print
print "@f"; # print field names
}
if ($. == 1) { # if line number 1
@n = @F; # get all field names
} else { # or else
@v{@n} = @F; # map field names to values
print "@v{@f}"; # print values based on names
}
답변4
가격 대비 좋은 가치. 선택한 출력 순서에 관계없이 소스의 열 수와 인쇄할 열 수를 처리할 수 있습니다.
예를 들어. 부르다:script-name id age
outseq=($@)
colnum=($(
for ((i; i<${#outseq[@]}; i++)) ;do
head -n 1 file |
sed -r 's/ +/\n/g' |
sed -nr "/^${outseq[$i]}$/="
done ))
tr ' ' '\t' <<<"${outseq[@]}"
sed -nr '1!{s/ +/\t/gp}' file |
cut -f $(tr ' ' ','<<<"${colnum[@]}")
산출
id age
1 50
2 70