텍스트 파일의 특정 열(내 경우에는 열 4)이 새 텍스트 파일의 마지막 열로 추가되는 루프를 만들고 싶습니다. 네 번째 열을 가져와 새 텍스트 파일(탭으로 구분된 열)에 추가하려는 총 약 500개의 텍스트 파일(V1-V500)이 있습니다. 모든 텍스트 파일의 줄 수는 동일합니다. 또한 추가된 열의 헤더에는 해당 열이 원래 제공된 텍스트 파일의 파일 이름이 포함되어야 합니다. awk와 for 루프를 사용하여 명령줄을 구성해 보았지만 어떤 명령도 작동하지 않습니다. 이전 명령줄을 기반으로 명령줄을 사용해 보았습니다.우편 엽서. 저는 사용 가능한 GNU 도구를 사용하여 Linux에서 작업하고 있습니다.
예: V1 텍스트 파일
header1 header2 header3 header4
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
V2 텍스트 파일:
header1 header2 header3 header4
17 25 21 29
18 26 22 30
19 27 23 31
20 28 24 32
새 텍스트 파일:
V1 V2
13 29
14 30
15 31
16 32
당신의 도움을 주셔서 감사합니다!
답변1
awk
모든 파일을 구문 분석합니다 .
awk -F'\t' -v OFS='\t' '{
x = (FNR==1 ? FILENAME : $4)
a[FNR] = (FNR==NR ? x : a[FNR] OFS x)
}
END {
for (i=1;i<=FNR;i++) print a[i]
}' V{1..500}
x
a
이는 우리 가 구축하는 모든 라인과 새로운 라인 에서 이어오는 것입니다 . 둘 다 할당을 사용합니다.조건식. FNR
현재 입력 파일의 줄 번호와 NR
총 줄 수입니다. FNR==NR
"첫 번째 파일을 구문 분석할 때"를 의미합니다. 또한 탭으로 구분된 입력 및 출력을 가정했습니다.
답변2
비 awk 솔루션:
#!/bin/bash
for num in {1..500}; do
echo V$num > temp_$num #put the filename as header
< V$num tail -n+2 | cut -f4 >> temp_$num #get the contents of column 4
if [[ -f V_new ]]; then #if not first iteration
paste V_new temp_$num > temp #combine previous files with current file
mv temp V_new
else # if first iteration
mv temp_$num V_new
fi
done
답변3
awk나 다른 도구를 사용하여 이 작업을 수행할 수 있지만 여기서는 더 간단한 접근 방식을 권장합니다.
$ printf 'paste ' > script
$ printf "<(awk 'NR==1{print FILENAME; next}{print \$4}' %s) \\\\\n" V{1..500} >> script
$ sh ./script
그러면 paste
파일에 script
다음과 같은 복잡한 명령이 생성됩니다.
$ head script
paste <(awk 'NR==1{print FILENAME; next}{print $4}' V1) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V2) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V3) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V4) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V5) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V6) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V7) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V8) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V9) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V10) \
따라서 script
awk 명령을 사용하여 실행이 실행되어 500개 입력 파일 각각의 4번째 열을 추출합니다. paste
예제의 두 파일을 사용하면 다음이 생성됩니다.
$ printf 'paste ' > script
$ printf "<(awk 'NR==1{print FILENAME; next}{print \$4}' %s) \\\\\n" V* >> script
$ sh ./script
V1 V2
13 29
14 30
15 31
16 32
답변4
awk를 사용하여 for 루프에 붙여넣은 솔루션:
- 첫 번째 파일의 열 4를 작성합니다(파일 이름을 헤더로 사용)
NEW
.
awk -F'\t' 'NR==1{print FILENAME; next} {print $4}' V1 > NEW
NEW
for 루프 에 다른 파일(파일 이름을 헤더로 사용)의 열 4를 추가합니다 . 임시 파일(temp
)을 사용하여 출력을 수집한 다음 해당 내용을NEW
각 반복으로 이동합니다.
for file in V{2..500}; do
paste NEW <(awk -F'\t' 'NR==1{print FILENAME; next} {print $4}' $file) > temp && mv -f temp NEW
done