내 첫 번째 파일에는 screen.txt
다음과 같은 단일 문자가 포함되어 있습니다.
d
m
a
o
두 번째 파일 beta.txt
에는 여러 줄이 포함되어 있습니다.
cvvbbe
etgjiua
qwrfggo
세 번째 파일 gama.sh
은 쉘 스크립트입니다.
beta.txt
다음과 같이 파일을 반복해야 합니다.
- 각 줄의 마지막 문자를
beta.txt
첫 번째 문자로 바꿉니다.screen.txt
- 구하다
beta.txt
- 달리기
gama.sh
- 각 줄의 마지막 문자를
beta.txt
두 번째 문자로 바꿉니다.screen.txt
- 구하다
beta.txt
- 달리기
gama.sh
- 등.
답변1
awk를 사용하십시오.
$ cat gama.sh
#!/usr/bin/env sh
awk '
NR==FNR {
beta[++nr] = substr($0,1,length($0)-1)
next
}
{
for ( i=1; i<=nr; i++ ) {
print beta[i] $0 > ARGV[1]
}
print "" > ARGV[1]
}
' "$@"
$ ./gama.sh beta.txt screen.txt
$ cat beta.txt
cvvbbd
etgjiud
qwrfggd
cvvbbm
etgjium
qwrfggm
cvvbba
etgjiua
qwrfgga
cvvbbo
etgjiuo
qwrfggo
위의 내용은 내용이 beta.txt
메모리에 맞지 않을 정도로 크지 않다고 가정합니다. 그렇지 않은 경우 내용이 screen.txt
메모리에 맞는 경우:
$ cat gama.sh
#!/usr/bin/env sh
tmp=$(mktemp) &&
awk '
BEGIN { OFS="\t" }
NR==FNR {
screen[++nr] = $0
next
}
{
$0 = substr($0,1,length($0)-1)
for ( i=1; i<=nr; i++ ) {
print i, FNR, $0 screen[i]
}
}
END {
for ( i=1; i<=nr; i++ ) {
print i, FNR+1
}
}
' "$@" |
sort -k1,2n |
cut -f3- > "$tmp" &&
mv -- "$tmp" "$2"
$ ./gama.sh screen.txt beta.txt
$ cat beta.txt
cvvbbd
etgjiud
qwrfggd
cvvbbm
etgjium
qwrfggm
cvvbba
etgjiua
qwrfgga
cvvbbo
etgjiuo
qwrfggo
두 번째 스크립트는 DSU(장식/정렬/장식 취소) 관용구를 적용하여 원하는 순서로 출력 라인을 생성합니다.https://stackoverflow.com/questions/71691113/how-to-sort-data-based-on-the-value-of-a-column-for-part-multiple-lines-of-af/71694367#71694367더 알아보기.
답변2
sed
다음과 같은 루프로 실행할 수 있습니다 .
$ while read letter; do
printf '%s\n\n' "$(sed "s/.$/$letter/" beta.txt)";
done < screen.txt > tmpFile && mv tmpFile beta.txt
$ cat beta.txt
cvvbbd
etgjiud
qwrfggd
cvvbbm
etgjium
qwrfggm
cvvbba
etgjiua
qwrfgga
cvvbbo
etgjiuo
qwrfggo
스크립트로 원하는 경우 다음과 같이 저장할 수 있습니다 gamma.sh
.
#!/bin/sh
tmpFile=$(mktemp)
while read letter; do
printf '%s\n\n' "$(sed "s/.$/$letter/" beta.txt)";
done < screen.txt > "$tmpFile" && mv tmpFile
이는 대용량 파일의 경우 매우 느리고 비실용적입니다. 제공한 더미 예제에서는 괜찮지만 수천 또는 심지어 수백 줄을 처리해야 한다면 다른 언어를 사용해야 합니다. 예를 들어 Perl에서는 다음과 같습니다.
#!/usr/bin/perl
use strict;
use warnings;
my @letters;
open(my $letterFile, '<', "$ARGV[0]") or
die("Failed to open letter file '$ARGV[0]':$!\n");
while (my $line = <$letterFile>) {
chomp($line);
$line =~ /(.)\s*$/;
push @letters, $1;
}
close($letterFile);
open(my $dataFile, '<', "$ARGV[1]") or
die("Failed to open data file '$ARGV[1]':$!\n");
my @data = <$dataFile>;
my $c = 0;
foreach my $letter (@letters) {
print "\n" if $c;
foreach my $line (@data) {
$line =~ s/.$/$letter/;
print "$line";
}
$c++;
}
close($dataFile);
위 스크립트를 다음과 같이 저장하면 foo.pl
:
$ perl foo.pl screen.txt beta.txt
cvvbbd
etgjiud
qwrfggd
cvvbbm
etgjium
qwrfggm
cvvbba
etgjiua
qwrfgga
cvvbbo
etgjiuo
qwrfggo
이는 모든 것을 beta.txt
메모리에 저장하므로 대용량 파일의 경우 문제가 될 수 있습니다. 이것이 문제라면 다른 접근 방식이 필요하지만 이는 현재 질문의 범위를 벗어납니다.