다음과 같은 데이터 목록이 있습니다.
12345
23456
67891
-20000
200
600
20
...
이 데이터 세트(즉, 파일 행)의 크기가 N
. m
이 데이터 파일에서 임의의 선을 그리고 싶습니다 . 따라서 출력은 두 개의 파일이어야 합니다. 하나는 이러한 m
데이터 행을 포함하고 다른 하나는 이러한 N-m
데이터 행을 포함합니다.
Linux 명령을 사용하여 이를 수행할 수 있는 방법이 있습니까?
답변1
이는 가장 효율적인 접근 방식은 아니지만 다음과 같이 작동합니다.
shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2
$m
행 수를 포함합니다 .
답변2
이 bash/awk 스크립트는 행을 무작위로 선택하고 두 개의 출력 파일에서 원래 순서를 유지합니다.
awk -v m=4 -v N=$(wc -l <file) -v out1=/tmp/out1 -v out2=/tmp/out2 \
'BEGIN{ srand()
do{ lnb = 1 + int(rand()*N)
if ( !(lnb in R) ) {
R[lnb] = 1
ct++ }
} while (ct<m)
} { if (R[NR]==1) print > out1
else print > out2
}' file
cat /tmp/out1
echo ========
cat /tmp/out2
질문의 데이터를 기반으로 한 출력입니다.
12345
23456
200
600
========
67891
-20000
20
답변3
Unix의 모든 것과 마찬가지로 Utility for That TM이 있습니다 .
오늘의 프로그램: split
split
파일을 다양한 방법, -b
바이트, -l
줄, -n
출력 파일 수로 분할합니다. 우리는 이 옵션을 사용할 것입니다 -l
. 첫 번째 행뿐만 아니라 임의의 행을 선택하려고 하므로 파일을 무작위로 선택하는 것부터 시작합니다 m
. sort
이에 대해 알고 싶다면 sort
내 답변을 참조하십시오.여기.
이제 실제 코드입니다. 정말 간단합니다.
sort -R input_file | split -l $m output_prefix
이렇게 하면 두 개의 파일이 생성됩니다. 하나는 m
행을 포함하고 다른 하나는 및 N-m
이름의 행을 포함합니다. 원하는 파일이 더 큰지 확인하세요 . 그렇지 않으면 같은 길이의 여러 파일 (하나는 )이 생성됩니다.output_prefixaa
output_prefixab
m
m
N % m
올바른 치수를 사용하고 있는지 확인하려면 다음 코드를 사용하세요.
m=10 # size you want one file to be
N=$(wc -l input_file)
m=$(( m > N/2 ? m : N - m ))
sort -R input_file | split -l $m output_prefix
편집: 일부 구현에는 플래그가 sort
없는 것으로 나타났습니다 . -R
가능한 경우 perl
교체할 수 있습니다 perl -e 'use List::Util qw/shuffle/; print shuffle <>;'
.
답변4
가정 m = 7
하고 N = 21
:
cp ints ints.bak
for i in {1..7}
do
rnd=$((RANDOM%(21-i)+1))
# echo $rnd;
sed -n "${rnd}{p,q}" 10k.dat >> mlines
sed -i "${rnd}d" ints
done
참고: 또는 와 같은 변수를 대체하는 경우 7
대신 변수 확장을 수행하지 않는 - 표기법을 사용해야 합니다.$1
$m
seq
{from..to}
파일에서 한 줄씩 삭제하는 방식으로 작동하는데, 파일이 점점 짧아지므로 삭제할 수 있는 줄 번호도 점점 작아져야 합니다.