사용자가 정의한 줄 수와 줄당 문자 수를 사용하여 0과 1의 무작위 시퀀스로 파일을 채우려고 합니다.
첫 번째 단계는 0과 1의 무작위 스트림을 얻는 것입니다.
cat /dev/urandom | tr -dc 01
그런 다음 이 스트림으로 파일을 채우려고 합니다(그리고 Ctrl+C를 통해 채우기 프로세스를 종료합니다).
cat /dev/urandom | tr -dc 01 > foo
이렇게 생성된 foo 파일의 줄 수를 세어보니 0 줄이 나옵니다.
cat foo | wc -l 0
이제 흐름을 제어하려고 하므로 명명된 파이프를 만들고 그 안으로 흐름을 지정합니다. 그런 다음 줄당 문자 수와 파일의 줄 수를 제어하려는 헛된 희망으로 dd 명령을 사용하여 명명된 파이프에 연결했습니다.
makefifo namedpipe
cat /dev/urandom | tr -dc 01 > namedpipe
dd if=namedpipe of=foo bs=10 count=5
foo 파일은 실제로 50바이트의 0과 1로 채워져 있지만 행 수는 여전히 0입니다.
이 문제를 어떻게 해결합니까? 파일의 각 문자 수에 대해 개행 문자를 삽입해야 할 것 같은데, 그렇다면 어떻게 해야 할지 모르겠습니다.
답변1
어때요 fold
? coreutils의 일부입니다 ...
$ tr -dc 01 < /dev/urandom | fold -w 30 | head -n 5
001010000111110001100101101101
000101110011011100100101111000
111010101011100101010110111001
111011000000000101111110110100
110011010111001110011010100011
또는 사용할 수 없는 경우 다음을 사용할 수 있습니다 awk
.
$ tr -dc 01 < /dev/urandom | awk \$0=RT RS=.\{,30} | head -n 5
000100010010001110100110100111
101010010100100110111010001110
100011100101001010111101001111
010010100111100101101100010100
001101100000101001111011011000
아니면 루프로 뭔가를 할 수도 있습니다 ...
$ for line in $(seq 1 5)
> do
> echo $(tr -dc 01 < /dev/urandom | head -c 30)
> done
100101100111011110010010100000
000000010000010010110111101011
010000111110010010000000010100
001110110001111011101011001001
001010111011000111110001100110
다른 방법이 있을 거라고 확신합니다... 맞춤 형식을 사용하는 hexdump를 사용하면 가능하다고 생각했지만 분명히 그렇지는 않았습니다... ;)
답변2
LC_ALL=C </dev/urandom \
tr '\0-\377' '[0*128][1*]' |
dd ibs=50 cbs=10 conv=unblock count=1
이것은 모든 입력 ASCII 바이트를 변환합니다(지정된 대로 모든 바이트가 됩니다 LC_ALL=C
)균일하게 분포된 0 또는 1 중 하나로 변환됩니다. \0
과 사이의 처음 128바이트는 \177
0과 1로 변환됩니다 \200-\377
. 따라서 모든 입력 바이트를 사용하면서도 1이나 0만 포함하는 무작위 순서의 시퀀스를 출력할 수 있습니다.
선택은 정확 하지만 5개의 11바이트 출력 행을 얻기 위해 블록 크기를 dd
설정할 필요는 없습니다.bs=
(10 \n
줄 이상)조각. 대신 count=1
입력 바이트 블록에 대해 단일 바이트를 지정한 다음 이를 5개의 크기 변환 블록으로 분할하고 모든 후행 공백을 제거한 후 각 변환 블록에 ewline을 추가하여 cbs 크기별로 편집해야 합니다.read()
ibs=50
cbs=10
conv=unblock
\n
(너는 ..하지 않았다).
그래서 실행해 보니 다음과 같이 인쇄되었습니다.
1101001010
1100001001
1101110100
1011011000
1011110100
1+0 records in
0+1 records out
55 bytes (55 B) copied, 0.00176591 s, 31.1 kB/s
dd
또한 한 방법과 다른 방법 간의 속도 비교를 보여주고 쓰기 유틸리티 buffer-size의 블록 요소를 읽는 경우 파이프에서 읽는 것이 문제가 되지 않음을 보여주기 위해 분담금을 약간 올렸습니다 . 그래서 먼저 다음을 수행했습니다.
time (
LC_ALL=C </dev/urandom \
tr -dc 01 |
dd ibs=4k cbs=10 conv=unblock count=k|
grep \[^01])
...표준 출력에 출력 없음(따라서 grep
0 또는 1 이외의 일치 항목은 없습니다)stderr에 다음을 표시합니다.
1024+0 records in
9011+1 records out
4613735 bytes (4.6 MB) copied, 25.8898 s, 178 kB/s
( LC_ALL=C tr -dc 01 < /dev/urandom |\
dd ibs=4k cbs=10 conv=unblock count=k |...)\
0.80s user 25.42s system 101% cpu 25.921 total
위 정보를 보면 파이프라인이 시스템 호출을 기다리는 데 25.5초가 소요되었음을 알 수 있습니다. 좋아요 하지만 dd
4096바이트 입력 레코드 중 1024개를 모두 읽는다는 것도 알려줍니다.완전히그리고 read()
조기 반환으로 인해 잘린 부분은 없습니다. 이는 tr
버퍼가 4k 청크에서 파이프아웃되기 때문입니다.
어쨌든 다음은 다른 방법으로 수행하거나 확산 스펙트럼의 모든 무작위 입력을 변환하는 것입니다.
time (
LC_ALL=C </dev/urandom \
tr '\0-\377' '[0*128][1*]' |
dd ibs=4k cbs=10 conv=unblock count=k|
grep '[^01]')
다시 한번 말하지만, 표준 출력에는 아무것도 없습니다.모두출력 은 dd
0, 1 또는 개행 중 하나입니다. 이는 stderr에 있습니다.
1024+0 records in
9011+1 records out
4613735 bytes (4.6 MB) copied, 0.554202 s, 8.3 MB/s
( LC_ALL=C tr '\0-\377' '[0*128][1*]' \
< /dev/urandom|dd ibs=4k cbs=10 ...)\
0.61s user 0.36s system 171% cpu 0.571 total
...이는 dd
전체 입력 레코드 1024개 + 잘린 입력 레코드 0개를 읽는 것을 다시 보여 주지만 처리 시간은 크게 다릅니다. 여기에서 실제로 별도의 코어에서 병렬로, 집합적으로 작업할 수 있다는 것은 전체 프로세스가 0.6초 이내에 완료되는 데 걸리는 시간보다 더 많은 시간이 걸렸습니다 tr
. dd
이것이 더 빠를 것입니다.
답변3
생성 중에 개행을 추가하려면 다음을 수행하십시오.
{ process-without-terminating-newline ; echo ;} > outfile
기존 파일에 추가하려면 다음을 수행하십시오.
echo >> outfile
답변4
그런 다음 이 스트림으로 파일을 채우려고 합니다(그리고 Ctrl+C를 통해 채우기 프로세스를 종료합니다).
cat /dev/urandom | tr -dc 01 > foo
이렇게 생성된 foo 파일의 줄 수를 세어보니 0 줄이 나옵니다.
cat foo | wc -l 0
둘다cat
tr
완충기그들의 출력. Ctrl+ 를 누르면 C명령 버퍼에 남아 있는 모든 데이터가 손실됩니다 . 전체 버퍼 값이 누적되기 전에 프로그램을 아주 일찍 중단했기 tr
때문에 아무것도 쓰지 않았습니다.
dd
문자 장치나 파이프에서 읽는 데 사용하지 마십시오 ..
head
Linux에서는 특정 바이트 수 이후의 데이터 자르기를 사용할 수 있습니다 .
i=0
while [ "$i" -lt "$number_of_lines" ]; do
</dev/urandom tr -dc 01 | head -c "$bits_per_line"; echo
i=$((i+1))
done >foo
또는 필요한 바이트 수를 생성하고 이를 사용하여 fold
줄바꿈을 삽입합니다.
</dev/urandom tr -dc 01 |
fold -w "$bits_per_line" |
head -n "$number_of_lines"
느리지 않거나 매우 느린 모든 바이트를 거부합니다 0
. 1
입력의 127/128을 거부합니다. 기본 2 출력을 생성할 수 있는 표준 유틸리티는 없지만 이를 사용하여 od
16진수를 생성하고 비트 단위로 변환할 수 있습니다.
</dev/urandom od -An -tx1 |
sed 's/ //g; s/0/@@@@/g; s/1/@@@`/g; s/2/@@`@/g; s/3/@@``/g; s/4/@`@@/g; s/5/@`@`/g; s/6/@``@/g; s/7/@```/g; s/8/`@@@/g; s/9/`@@`/g; s/[Aa]/`@`@/g; s/[Bb]/`@``/g; s/[Cc]/``@@/g; s/[Dd]/``@`/g; s/[Ee]/```@/g; s/[Ff]/````/g; y/@`/01/' |
fold -w "$bits_per_line" |
head -n "$number_of_lines"
그렇다면 xxd
이를 사용하여 바이트를 base-2 표현으로 변환할 수 있습니다. 줄당 자릿수가 8의 배수인 경우 해당 -c
옵션을 사용하여 필요할 때 줄 바꿈을 삽입하고 -l
몇 줄 후에 중지하도록 할 수도 있습니다.
</dev/urandom xxd -b -c "$bytes_per_line" -l "$((bytes_per_line * number_of_lines))" |
sed -e 's/ .*//' -e 's/.*://'