file1
2, 6, 7 행을 각 행의 값으로 바꾸고 다음 file2
과 같은 계열을 생성하고 싶습니다 .wc -l file2
cat file1
w
3
y
G
7
1.2
Q
cat file2
1 1 1
6 6 7
5 6 5
예상 결과:
cat out1
w
1
y
G
7
1
1
cat out2
w
6
y
G
7
6
7
cat out3
w
5
y
G
7
6
5
답변1
awk '
FNR == NR { data[++n] = $0; next }
{
data[2] = $1; data[6] = $2; data[7] = $3;
outname = sprintf("out%d", FNR) # or: outname = "out" FNR
for (i = 1; i <= n; ++i)
print data[i] >outname
close(outname)
}' file1 file2
file1
이 내용을 먼저 읽은 다음 읽습니다 file2
.
file1
( 청크로) 읽는 동안 FNR == NR
코드가 하는 유일한 작업은 awk
각 행을 배열에 저장하는 것입니다 data
.
읽을 때 file2
코드는 파일의 한 줄에 있는 세 개의 필드를 각각 가져와서 data
변경할 줄에 해당하는 인덱스 에 할당합니다 file1
.
그런 다음 저장된 줄은 현재 줄 번호를 취하고 그 앞에 문자열을 추가하여 구성된 파일 이름 data
으로 인쇄 됩니다 .file2
out
close(outname)
awk
이는 GNU가 아닌 다른 것을 사용 awk
하고 기록된 파일 수가 열린 파일 설명자 제한을 초과하는 경우에만 실제로 필요합니다( ulimit -n
반환된 수 초과, 표준 스트림의 경우 3개 뺀 값).
시험:
$ tree
.
|-- file1
`-- file2
0 directory, 2 files
$ awk '
FNR == NR { data[++n] = $0; next }
{
data[2] = $1; data[6] = $2; data[7] = $3;
outname = sprintf("out%d", FNR)
for (i = 1; i <= n; ++i)
print data[i] >outname
close(outname)
}' file1 file2
$ tree
.
|-- file1
|-- file2
|-- out1
|-- out2
`-- out3
0 directory, 5 files
$ paste out[123]
w w w
1 6 5
y y y
G G G
7 7 7
1 6 6
1 7 5
답변2
$ cat tst.awk
BEGIN {
split("2 6 7",tmp)
for (fldNr in tmp) {
map[tmp[fldNr]] = fldNr
}
}
NR==FNR {
rows[++numRows] = $i
next
}
{
out = "out" FNR
for (rowNr=1; rowNr<=numRows; rowNr++) {
print (rowNr in map ? $(map[rowNr]) : rows[rowNr]) > out
}
close(out)
}
$ awk -f tst.awk file1 file2
$ head out?
==> out1 <==
w
1
y
G
7
1
1
==> out2 <==
w
6
y
G
7
6
7
==> out3 <==
w
5
y
G
7
6
5
답변3
사용GNU sedout_0/1/2 파일에 있는 file2의 각 줄의 출력을 얻습니다.
tmpf=$(mktemp) i=0
while read -ra a <&3
do
printf '%s\n' "${a[@]}" > "$tmpf"
sed -ne "
$(printf '%dba\n' 2 6 7)
p;d;:a
R $tmpf
" file1 > "out_$i"
(( i++ ))
done 3< file2
- while 루프에서 file2를 읽고 공백으로 구분된 필드를 줄 바꿈으로 구분된 필드로 변환하고 임시 파일에 저장합니다.
- get sed는 원하는 출력을 얻기 위해 file1의 라인 2,6,&7에서 R 명령을 호출합니다.