![배열의 보수를 찾으시나요?](https://linux55.com/image/65862/%EB%B0%B0%EC%97%B4%EC%9D%98%20%EB%B3%B4%EC%88%98%EB%A5%BC%20%EC%B0%BE%EC%9C%BC%EC%8B%9C%EB%82%98%EC%9A%94%3F.png)
다음에서이 문제, 파일에서 임의의 10줄을 추출하고 싶었고 이제 나머지 90줄을 별도의 파일로 원합니다.
문서에는 1부터 100까지의 인덱스가 있는 100개의 행이 있으므로 문제는 find 의 보수로 귀결 됩니다 ind
.1, 2, ..., 100
ind=$(shuf -i 1-100 -n 10 | sort -n)
그래서 내 질문은
1, 2, ..., 100
배열을 효율적으로 생성하는 방법은 무엇입니까 ? 그리고- 완성하는데 사용할 수 있을 것 같습니다
comm
. 그렇다면comm
파일 대신 배열을 어떻게 처리해야 합니까?
답변1
다른 스레드의 내 제안을 바탕으로:
awk '
BEGIN { srand(); do a[int(100*rand()+1)]; while (length(a)<10) }
NR in a
' ~/orig.txt > ~/short.txt
이를 변경하여 두 개의 파일을 만들 수 있습니다.
awk -v range=100 -v offset=1 -v amount=10 '
BEGIN { srand(); do a[int(range*rand()+offset)]; while (length(a)<amount) }
NR in a { print > "short.txt" }
!(NR in a) { print > "rest.txt" }
' ~/orig.txt
(이것은 내부적으로 awk
사용할 수 없습니다 ~
. 그러나 HOME
through는 ENVIRON[]
다음과 같이 사용할 수 있습니다: print > ENVIRON["HOME"] "/short.txt"
또는 resp., print > ENVIRON["HOME"] "/rest.txt"
.)
답변2
글쎄, 다시 생각해보니 - 난 일을 했어방법너무 어렵다. 필요한 것은 이것뿐입니다:
shuf -i 1-100 -n10 |
sed 's/$/{p;b\n}/' |
sed -nf - -e 'w separate_file' infile >outfile
n
교체 대신 리터럴 개행 문자가 필요할 수도 있습니다 sed
. 어쨌든, 이는 아래와 같은 일을 합니다. 다른 90줄을 모두 실행하는 데 방해가 되지 않습니다. 파일에 있기 때문에 제자리에 있을 뿐이므로 특별히 고려할 필요가 없습니다.
전체 거래는 다음과 같습니다.
set " $(shuf -i 1-100 -n 10) "
while [ "$((i+=1))" -le 100 ]
do [ -z "${1##*[!0-9]$i[!0-9]*}" ]
printf "$i%.$((!$?))s%.$?s\n" p H
done| sed -nf - -e '$!d;x;s/.//p' <infile >outfile
기본적으로 sed
다음과 같은 스크립트를 작성합니다.
1H
2H
3H
4p
5H
...
90p
91H
...
그리고 100까지 계속됩니다. 마지막 줄에서 - 무작위로 선택된 모든 줄이 p
인쇄 된 후 이전 공백 x
으로 변경 하고 처음 삽입된 ewline 문자를 바꾸고 나머지를 인쇄합니다.H
s///
\n
p
셸 루프 없이 이를 수행하려면 다음을 수행할 수 있습니다.
set "$(shuf -i 1-100 -n 10)"
{ seq 100 | grep -Fxv "$1"; echo "$1"; } |
sed '1,90s/$/H/;91,$s/$/p/' |
sed -nf - -e '$!d;x;s/.//p' <infile >outfile
하지만 이 규모에서는 그것이 도움이 될지 확신할 수 없습니다.
아무튼 seq 100
출력파일을 테스트삼아 실행해보고 출력해봤는데..
3
4
5
19
57
63
64
73
80
88
1
2
6
7
8
9
10
11
12
13
14
15
16
...
...초기 무작위 100에 포함되지 않은 모든 행에 대해 최대 100입니다.
답변3
bash를 사용하는 또 다른 솔루션은 다음과 같습니다. 먼저 ind 변수에서 배열을 생성할 수 있습니다.
ind=($(shuf -i 1-100 -n 10 | sort -n))
1..100 범위의 숫자를 포함하는 배열을 만들려면 간단한 방법은 다음과 같습니다.
numbers=({1..100})
보완을 얻으려면 uniq -u를 사용합니다. 이 명령은 정렬된 목록에서 모든 중복 항목을 정렬합니다. 마지막 붙여넣기 명령은 모든 값을 다시 한 줄에 넣습니다.
complement=($(echo ${ind[*]} ${numbers[*]} | sed 's/ /\n/g' | sort -n | uniq -u | paste -sd " " - ))
echo ${complement[*]}
질문을 다시 생각해 보면 이 모든 것은 bash 배열 없이도 수행될 수 있습니다.
ind=$(shuf -i 1-100 -n 10 | sort -n)
echo $ind {1..100} | sed 's/ /\n/g' | sort -n | uniq -u | paste -sd " " -
답변4
명령줄에서 모든 작업을 수행할 수 있다고 확신하지만 실제 프로그래밍 언어를 사용하면 일부 문제를 더 잘 해결할 수 있습니다. 예를 들어 문제에 대한 Python 기반 솔루션은 다음과 같습니다.
import random
import pprint
with open("file.txt", "w") as f:
# create a file filled with numbers from 00 to 99
f.writelines(map(lambda x: "%02d\n" % x, range(100)))
with open("file.txt") as f:
# read it and assign each line to array, strip newlines
ar = set(map(lambda x: x.strip(), f.readlines()))
selection = set(random.sample(ar, 10))
rest = ar - selection
pprint.pprint(selection)
pprint.pprint(rest)