Deux parties à cela, pour moi - d'abord - utiliser cat pour sortir le fichier texte sur la sortie standard, et utiliser append pour l'ajouter à un autre fichier - par exemple foo.txt>>bar.txt ajoutera foo.txt à bar.txt
puis exécutez-le n fois avec
for i in {1..n};do cat foo.txt >> bar.txt; done
en remplaçant n dans cette commande par votre numéro
devrait fonctionner, où n est votre numéro
Si vous utilisez csh, il y a la commande 'repeat'.
répéter les parties liées de la réponse sont copiées à partir d'ici, et je l'ai testé sur un système ubuntu 11.04 sur le shell bash par défaut.
Vous pouvez certainement utiliser cat
pour cela :
$ cat /tmp/f
foo
$ cat /tmp/foo /tmp/f
foo
foo
Pour obtenir $n
copies, vous pouvez utiliser yes
redirigé vers 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
Mettre cela ensemble donne
yes /tmp/f | head -n $n | xargs cat >/tmp/output
Je m'ennuie alors voici quelques méthodes supplémentaires pour concaténer un fichier à lui-même, principalement avec head
comme béquille. Pardonnez-moi si je me surexplique, j'aime juste dire des choses :P
En supposant N
est le nombre d'auto-concaténations que vous voulez faire et que votre fichier s'appelle file
.
Variables :
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)
Étant donné une copie de file
appelé file2
, total_repeats
est le nombre de fois file
devrait être ajouté à file2
pour en faire la même chose que si file
a été concaténé à lui-même N
fois.
Dit MATH est ici, plus ou moins :MATH (essentiel)
C'est un truc d'informatique du premier semestre mais ça fait un moment que je n'ai pas fait de preuve d'induction donc je ne peux pas m'en remettre... (aussi cette classe de récursivité est assez bien connue pour être 2^Loops
donc il y a ça aussi....)
POSIX
J'utilise quelques choses non positives mais elles ne sont pas essentielles.Pour mes besoins :
yes() { while true; do echo "$1"; done; }
Oh, je n'ai utilisé que ça. Eh bien, la section est déjà là...
Méthodes
head
avec suivi du nombre de lignes.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Pas de fichier temporaire, pas de chat, pas encore trop de maths, toute la joie.
tee
avec MATHS
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Ici tee
lit à partir de file
mais en y ajoutant perpétuellement, il continuera donc à lire le fichier en boucle jusqu'à head
l'arrête. Et nous savons quand l'arrêter grâce aux MATH . L'ajout va trop loin, j'ai donc utilisé un fichier temporaire. Vous pouvez couper les lignes en excès de file
aussi.
eval
, le seigneur des ténèbres !
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Cela s'étend simplement à cat file file file ...
et l'évalue. Vous pouvez le faire sans le $tmp
fichier, aussi :
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
Le deuxième head
"astuces" cat
en mettant un intermédiaire entre elle et l'opération d'écriture. Vous pourriez tromper cat
avec un autre cat
ainsi, mais qui a un comportement incohérent. Essayez ceci :
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
Force sed
en lisant le fichier entier comme une ligne, capture tout, puis le colle $total_repeats
nombre de fois.
Cela échouera bien sûr si vous avez des caractères nuls dans votre fichier. Choisissez-en un dont vous savez qu'il n'y est pas.
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
}
C'est tout pour le moment les gars, j'espère que cette réponse arbitraire n'a dérangé personne. Je les ai tous testés plusieurs fois, mais je ne suis qu'un utilisateur de shell depuis deux ans, alors gardez cela à l'esprit, je suppose. Dors maintenant...
rm $tmp