2011-01-09 2 views
2

, например, у меня есть текстовый файл с 5 строк:текстовый файл многократно Баш Linux

one 
two 
three 
four 
five 

и я хочу, чтобы сделать скрипт, чтобы сделать 2000 строк файла, содержащих петли файла выше и это будет выглядеть например

one 
    two 
    three 
    four 
    five 
    one 
    two 
    three 
    four 
    five 
    one 
    two 
    three 
    four 
    five 
............repeat until n times is reached 

ответ

0

Нужно ли быть подлинником? Если вы просто хотите быстро создать, что вы можете открыть на vim, вырежьте (нажмите esc, чем 5dd, чтобы сократить 5 строк), а затем вставьте n раз (нажмите esc, чем n p, чтобы вставить n раз).

Edit: если вы абсолютно нужен сценарий и эффективность не является проблемой, вы можете сделать это «грязный» трюк:

i=0; 
n=5; 
while(($i < $n)) ; do 
    cat orginal_file >> new_file; 
    let i+=1; 
done 
+1

Используйте цикл 'for' и пусть Bash управляет переменной. 'for ((i = 0; i

0
file_size() { 
    cat -- "[email protected]" |wc -l 
} 

mult_file() { 
    local \ 
     max_lines="$1" \ 
     iter_size \ 
     iters \ 
     i 

    shift 1 

    iter_size="$(file_size "[email protected]")" 

    let iters=max_lines/iter_size+1 

    (for ((i=0; i<iters; ++i)); do 
     cat -- "[email protected]" 
    done) | 
    head --lines="$max_lines" 
} 

mult_file "[email protected]" 

Таким образом, вы могли бы назвать его как script.sh LINES FILE1 FILE2 FILE3 >REPEAT_FILE.

2

Если вам нужно повторить 2000 раз

for i in {1..2000}; do cat "FILE"; done > NEW_FILE 
+1

Переместите перенаправление до конца, и это может быть немного быстрее (и используйте '>' вместо '>>', и вам не нужно будет беспокоиться о том, нужно ли сначала очистить файл). –

+0

@ Деннис Уильямсон - ** салют !!! ** – ajreal

+0

@ Dennis: Как можно перенаправить перенаправление в конец? Единственный способ, которым я могу думать, - включить цикл в функцию. Например. вызовите функцию 'repeat' и выполните' repeat '$ {INPUT} ">" $ {OUTPUT} "'. Это по-прежнему медленный метод, потому что 'cat' вызывается 2000 раз. –

5

Тестирование показало, что это примерно в 100 раз быстрее, чем следующий лучший подход данного до сих пор.

#!/bin/bash                  

IN="${1}" 
OUT="${2}" 

for i in {1..2000}; do 
    echo "${IN}" 
done | xargs cat > "${OUT}" 

Причина это так намного быстрее, потому что это не раз открыто, стремиться к концу, добавьте, и закройте выходной файл. Он открывает выходной файл один раз и передает данные ему в одну большую непрерывную запись. Он также вызывает cat как можно больше раз. Он может вызывать cat только один раз, даже в зависимости от максимальной длины командной строки системы и длины имени входного файла.

+0

Почему бы не 'echo" $ LIST ">" $ OUT "? Для чего нужны 'xargs' и' cat'? –

+0

@Dennis: 'echo '$ LIST"> "$ OUT" 'даст вам выходной файл, содержащий 2000 экземпляров имени входного файла. –

+0

О, я вижу, что вы там делали. Проблема с этим подходом заключается в том, что вы можете превысить ограничение длины аргумента. –

2

Вам нужны 2000 строк или 2000 копий исходного файла?

Если первый:

infile='/path/to/inputfile' 
outfile='/path/to/outputfile' 
len=$(wc -l < "$infile") 
for ((i=1; i<=2000/len; i++)) 
do 
    cat "$infile" 
done > "$outfile.tmp" # you can use mktemp or tempfile if you want 
head -n 2000 "$outfile.tmp" > "$outfile" 
rm "$outfile.tmp" 

Если вторая:

for i in {1..2000}; do cat "$infile"; done > "$outfile" 

Для небольшого входного файла (позволяет избежать накладных расходов на разветвление cat 2000 раз):

file=$(<"$infile"); for i in {1..2000}; do echo "$file"; done > "$outfile" 
0

Нет процесс в петле, без труб:

infile='5.txt' 
outfile='2000.txt' 

n=$((2000/ $(wc -l < "$infile")))  # repetitions 

> "$outfile"       # empty output file 

IFS='' 
content=$(cat "$infile")    # file content as string 

for ((CNTR=0; CNTR<n; CNTR+=1)); do 
    echo "$content" >> "$outfile" 
done 
Смежные вопросы