いくつかのアルゴリズムをベンチマークできる大きなテキストファイルを生成するために、Project Gutenbergからプレーンテキストファイルの本(約0.5MB)を自分でn
回連結したいと考えています。これを達成するために使用できるLinuxコマンドはありますか? cat
は理想的に聞こえますが、ファイルをそれ自体に連結することはあまりうまくいきませんし、質問のn
回の部分に直接対処しません。
これには2つの部分があります-最初に-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シェルのubuntu 11.04システムでテストしました。
これには確かにcat
を使用できます。
$ cat /tmp/f
foo
$ cat /tmp/foo /tmp/f
foo
foo
$n
のコピーを取得するには、head -n $n
にパイプされたyes
を使用できます。
$ 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
私は退屈なので、ファイルをそれ自体に連結する方法についていくつかの方法を紹介します。主に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 [〜#〜]
私はいくつかの非POSIXのものを使用しますが、それらは必須ではありません。私の目的のために:
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
一時ファイルも、猫も、数学もあまりありません。
tee
with[〜#〜]数学[〜#〜]
<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
2番目の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
にファイル全体を1行として読み取らせ、すべてをキャプチャしてから、$total_repeats
の回数だけ貼り付けます。
もちろん、ファイルにnull文字がある場合は失敗します。存在しないことがわかっているものを1つ選択してください。
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年間のShellユーザーなので、覚えておいてください。寝よう...
rm $tmp