开发者

text file multiply bash linux

开发者 https://www.devze.com 2023-02-03 02:01 出处:网络
for example i have a text file with 5 lines: one two three four five and i want to make a script to make a 2000 lines file containing loops of the file above

for example i have a text file with 5 lines:

one
two
three
four
five

and i want to make a script to make a 2000 lines file containing loops of the file above and it would look like

    one
    two
    three
    four
    five
    one
    two
    three
    four
    five
    one
    two开发者_如何学Go
    three
    four
    five
 ............repeat until n times is reached


Testing showed this to be about 100 times faster than the next best approach given so far.

#!/bin/bash                                                                     

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

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

The reason this is so much faster is because it doesn't repeatedly open, seek to end, append, and close the output file. It opens the output file once, and streams the data to it in a single large, continuous write. It also invokes cat as few times as possible. It may invoke cat only once, even, depending on the system's maximum command line length and the length of the input file name.


If you need to repeat 2000 times

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


Do you need 2000 lines or 2000 copies of the original file?

If the first:

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"

If the second:

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

For a small input file (avoids the overhead of forking cat 2000 times):

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


Does it need to be a script? If you just want to quickly generate that you can open on vim, cut (press esc than 5dd to cut 5 lines) and than insert n times (press esc than n p to paste n times).

Edit: if you absolutely need a script and efficiency is not a problem, you can do this "dirty" trick:

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


file_size() {
    cat -- "$@" |wc -l
}

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

    shift 1

    iter_size="$(file_size "$@")"

    let iters=max_lines/iter_size+1

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

mult_file "$@"

So you would call it like script.sh LINES FILE1 FILE2 FILE3 >REPEAT_FILE.


No process in the loop, no pipes:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消