파일을 n 번 연결하는 Linux 명령


31

Project Gutenberg (약 0.5MB)에서 일반 텍스트 파일 책을 가져 와서 n일부 알고리즘을 벤치 마크 할 수있는 큰 텍스트 파일을 생성하기 위해 자체 시간 으로 연결하려고합니다 . 이것을 달성하기 위해 사용할 수있는 리눅스 명령이 있습니까? cat이상적으로 들리지만 파일을 자체적으로 연결하는 데 너무 좋지 않은 것처럼 보이며 n질문 의 시간 부분을 직접 다루지 않습니다 .


2
어떤 종류의 루프를 사용하고 추가합니까? foo.txt >> bar.txt를 반복하고 명령을 여러 번 실행하는 것으로 감싸십시오.
Journeyman Geek

답변:


35

이것에 대한 두 부분-나에게-먼저-cat을 사용하여 텍스트 파일을 표준 출력으로 출력하고 append를 사용하여 다른 파일에 추가하십시오. 예를 들어 foo.txt >> bar.txt는 foo.txt를 bar.txt에 추가합니다

그런 다음 n 번 실행하십시오.

for i in {1..n};do cat foo.txt >> bar.txt; done

해당 명령에서 n을 숫자로 바꿉니다.

작동해야합니다. 여기서 n은 숫자입니다.

csh를 사용하면 'repeat'명령이 있습니다.

대답의 관련 부분을 여기 에서 복사 하고 기본 bash 쉘의 우분투 11.04 시스템에서 테스트했습니다.


3
재미있는 사실 : 이것은 실제로 'n'을 바꾸지 않고 작동합니다.이 경우 ASCII '1'과 ASCII 'n'사이의 각 문자마다 본문을 한 번 실행합니다 (따라서 62 번). 그러나 {1..12}몸을 12 번 올바르게 실행합니다.
Arnout Engelen

1
각 반복을 추가하는 대신 전체 파이프 라인을 리디렉션하고 싶을 수도 있습니다.for i in {1..n};do cat foo.txt; done > bar.txt
Toby Speight

2

지루해서 여기에 주로 head목발로 파일을 연결하는 방법에 대한 몇 가지 방법이 더 있습니다 . 내가 너무 많이 설명해 주면 용서해주세요.


N자체 연결 수를 가정 하고 파일 이름이이라고 가정 file합니다.

변수:

linecount=$(<file wc -l)

total_repeats=$(echo "2^$N - 1" | bc) # obtained through the power of MATH

total_lines=$((linecount*(total_repeats+1)))

tmp=$(mktemp --suffix .concat.self)

의 사본을 감안할 때 file호출 file2, total_repeats횟수가 file추가 될 필요 file2가 동일한 경우로 만들 file자신에게 연결된 한 N번.

상기 MATH 는 여기에 다소있다 : MATH (gist)

그것은 첫 학기 컴퓨터 과학 물건이지만 유도 증명을 한 이후로 그것을 극복 할 수 없었습니다 ... (이 클래스의 재귀는 꽤 잘 알려진 것으로도 알려져 2^Loops있습니다 ...)


POSIX

나는 몇 가지 비 poix를 사용하지만 필수는 아닙니다. 내 목적을 위해 :

 yes() { while true; do echo "$1"; done; }

오, 나는 단지 그것을 사용했다. 음, 섹션은 이미 여기에 있습니다 ...


행동 양식


head 라인 카운트 추적.

ln=$linecount
for i in $(seq 1 $N); do
    <file head -n $ln >> file;
    ln=$((ln*2))
done

임시 파일도없고, 고양이도없고, 너무 많은 수학조차도, 모든 기쁨도 없습니다.


teeMATH 와 함께

<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file

여기 tee에서 읽고 file있지만 영구적으로 추가하고 있으므로 파일을 head중지 할 때까지 반복해서 파일을 읽 습니다. 그리고 우리는 MATH 때문에 그것을 언제 막을 수 있는지 알고 있습니다. 추가는 오버 보드로 진행되므로 임시 파일을 사용했습니다. 초과 선도 잘라낼 수 file있습니다.


eval어둠의 군주!

eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file

이것은 단지 그것을 확장 cat file file file ...하고 회피합니다. $tmp파일 없이도 할 수 있습니다 .

eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
  head -n $((total_lines-linecount)) >> file

두 번째 head"트릭" cat은 중간에 사람과 쓰기 작업을 넣는 것입니다. cat다른 사람 cat과도 속일 수 있지만 일관성이 없습니다. 이 시도:

test_double_cat() {
    local Expected=0
    local Got=0
    local R=0
    local file="$(mktemp --suffix .double.cat)"
    for i in $(seq 1 100); do

        printf "" > $file
        echo "1" >> $file
        echo "2" >> $file
        echo "3" >> $file

        Expected=$((3*$(<file wc -l)))

        cat $file $file | cat >> $file

        Got=$(<file wc -l)

        [ "$Expected" = "$Got" ] && R="$((R+1))"
    done
    echo "Got it right $R/100"
    rm $file
}

sed:

<file tr '\n' '\0' |
    sed -e "s/.*/$(yes '\0' | head -n $total_repeats | tr -d '\n')/g" |
        tr '\0' '\n' >> file

부대 sed선으로 전체 파일을 읽기로는, 모든 그것의 캡처, 다음을 붙여 넣 $total_repeats횟수를.

파일에 널 문자가 있으면 물론 실패합니다. 당신이없는 것을 고르세요.

find_missing_char() {
  local file="${1:-/dev/stdin}"

  firstbyte="$(<$file fold -w1 | od -An -tuC | sort -un | head -n 1)"
  if [ ! "$firstbyte" = "0" ]; then
    echo "\0"
  else
    printf "\\$(printf '%03o\t' $((firstbyte-1)) )"
  fi
}

그게 다야 이제 젊은이들입니다.이 임의의 대답이 아무도 방해하지 않기를 바랍니다. 나는 그것들을 모두 여러 번 테스트했지만 2 년 쉘 사용자 일 뿐이므로 명심하십시오. 자자 ...

rm $tmp


2

당신은 확실히 cat이것을 사용할 수 있습니다 :

$ cat /tmp/f
foo
$ cat /tmp/foo /tmp/f
foo
foo

$n사본 을 얻으려면 다음으로 yes파이프를 사용할 수 있습니다 head -n $n.

$ yes /tmp/f | head -n 10
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f
/tmp/f

함께 모으면

yes /tmp/f | head -n $n | xargs cat >/tmp/output
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.