두 개의 파일이 있습니다.
file1
고유 단어 목록file2
여러 문장을 포함
file1
각 단어의 발생 횟수를 나열하는 탭으로 구분된 파일을 출력하고 싶습니다.file2
파일 1에 나열된 순서를 유지하면서.
예를 들어:
file 1
:dog apple cat
file 2
:the dog played with the cat and the cat was white. the boy ate the apple.
- 원하는 출력:
dog 1 apple 1 cat 2
나는 기존에 시도했다답변커뮤니티에서는 모두 출력을 정렬합니다.
답변1
모든 Unix 시스템의 모든 쉘에서 POSIX awk를 사용하십시오.
$ cat tst.awk
BEGIN { OFS="\t" }
NR==FNR {
words[NR] = $1
next
}
{
$0 = " " $0 " "
gsub(/[^[:alpha:]]+/," ")
for ( i in words ) {
word = words[i]
cnts[word] += gsub(" "word" ","&")
}
}
END {
for ( i=1; i in words; i++ ) {
word = words[i]
print word, cnts[word]+0
}
}
$ awk -f tst.awk file1 file2
dog 1
apple 1
cat 2
위의 내용에서는 "단어"가 모두 알파벳 문자이고 일치 항목이 대소문자를 구분하기를 원하거나 예제에서와 같이 입력이 모두 소문자이고 예제에서와 같이 file1의 단어가 고유하다고 가정합니다.
답변2
사용행복하다(이전 Perl_6)
@a
다음은 한 파일(배열로 저장됨)의 @b
줄을 두 번째 파일(배열로 저장됨)의 줄과 일치시키고 발생 횟수(예: Bag
ging)를 계산 하는 일반적인 솔루션입니다 .
raku -e 'my @a = dir(test => "alphabet.txt").IO.lines.reverse; my @b = $*ARGFILES.lines; \
for @a -> $a {@b.grep(/<$a>/).Bag.pairs.say};' alphabet.txt alphabet.txt
구성 시 Raku에는 위치와 파일 이름이 @a
제공됩니다 . 구성 시 명령줄에 하나 이상의 파일을 입력하고 Raku의 동적 변수를 통해 읽습니다.dir()
test => "…"
@b
$*ARGFILES
범용 입력예 alphabet.txt
, 한 줄에 한 글자씩, Raku로 읽은 후 즉시 뒤집어서 "z".."a" 순서로 배열을 배열합니다.
범용 출력alphabet.txt
(명령줄에 "a".."z"의 복사본 두 개를 입력하는 경우):
(z => 2)
(y => 2)
(x => 2)
(w => 2)
(v => 2)
(u => 2)
(t => 2)
(s => 2)
(r => 2)
(q => 2)
(p => 2)
(o => 2)
(n => 2)
(m => 2)
(l => 2)
(k => 2)
(j => 2)
(i => 2)
(h => 2)
(g => 2)
(f => 2)
(e => 2)
(d => 2)
(c => 2)
(b => 2)
(a => 2)
return이 array와 동일한 순서를 유지하는 방법 과 Raku가 위 출력을 생성하기 위해 @a
호출을 필요로 하지 않는 방법에 유의하세요.sort
my @b = $*ARGFILES.lines.words
마지막 으로 OP의 문제를 해결하기 위해 위 코드에서 변경해야 할 것은 my @b = $*ARGFILES.lines
.
[탭으로 구분된 출력을 얻으려면 위 코드에서 .put
대신 사용하십시오. .say
이렇게 하면 주변 대괄호와 =>
두 열 사이의 화살표가 제거됩니다.]
최종 코드:
~$ raku -e 'my @a = dir(test => "dog_apple_cat.txt").IO.lines.grep(*.chars); \
my @b = $*ARGFILES.lines.words; for @a -> $a { \
@b.grep(/<$a>/).Bag.pairs.put};' text.txt
dog 1
apple. 1
cat 2