Zwei Teile dazu, für mich - erstens - cat verwenden, um die Textdatei auf die Standardausgabe auszugeben, und append verwenden, um sie zu einer anderen Datei hinzuzufügen - zB foo.txt>>bar.txt wird foo.txt an bar.txt anhängen
dann n mal mit
ausführenfor i in {1..n};do cat foo.txt >> bar.txt; done
Ersetzen Sie n in diesem Befehl durch Ihre Nummer
sollte funktionieren, wobei n Ihre Nummer ist
Wenn Sie csh verwenden, gibt es den 'repeat'-Befehl.
Wiederholungsbezogene Teile der Antwort werden von hier kopiert, und ich habe sie auf einem Ubuntu 11.04-System auf der Standard-Bash-Shell getestet.
Sie können natürlich cat
verwenden dazu:
$ cat /tmp/f
foo
$ cat /tmp/foo /tmp/f
foo
foo
Um $n
zu erhalten Kopien, könnten Sie yes
verwenden in head -n $n
geleitet :
$ 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
Das zusammen ergibt
yes /tmp/f | head -n $n | xargs cat >/tmp/output
Ich langweile mich, also sind hier ein paar weitere Methoden, wie man eine Datei mit sich selbst verkettet, meistens mit head
als Krücke. Entschuldigen Sie, wenn ich mich zu viel erkläre, ich sage einfach gerne Dinge :P
Angenommen N
die Anzahl der Selbstverkettungen ist, die Sie durchführen möchten, und dass Ihre Datei file
heißt .
Variablen:
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)
Angesichts einer Kopie von file
genannt file2
, total_repeats
ist die Anzahl von file
müsste zu file2
hinzugefügt werden um es so zu machen, als ob file
wurde mit sich selbst verkettet N
Mal.
Sagte MATHE ist hier mehr oder weniger:MATH (Hauptinhalt)
Es ist Informatik-Zeug des ersten Semesters, aber es ist eine Weile her, seit ich einen Induktionsbeweis gemacht habe, also komme ich nicht darüber hinweg ... (auch diese Rekursionsklasse ist ziemlich bekannt als 2^Loops
also gibt es das auch....)
POSIX
Ich benutze ein paar Nicht-Posix-Dinge, aber sie sind nicht wesentlich. Für meine Zwecke:
yes() { while true; do echo "$1"; done; }
Oh, das habe ich nur benutzt. Naja, der Abschnitt ist schon da...
Methoden
head
mit Linecount-Tracking.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Keine temporäre Datei, keine Katze, noch nicht einmal zu viel Mathe, alles Freude.
tee
mit MATHE
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Hier tee
liest ab file
aber ständig anhängend, so dass es die Datei bei Wiederholung bis head
liest stoppt es. Und wir wissen aufgrund von MATH, wann wir damit aufhören müssen . Das Anhängen geht über Bord, also habe ich eine temporäre Datei verwendet. Sie könnten die überschüssigen Zeilen ab file
kürzen auch.
eval
, der Herr der Finsternis!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Dies wird einfach zu cat file file file ...
erweitert und wertet es aus. Sie können es ohne $tmp
machen Datei auch:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
Der zweite head
"Tricks" cat
indem ein Mittelsmann zwischen sie und die Schreiboperation gestellt wird. Sie könnten cat
austricksen mit einem weiteren cat
auch, aber das hat inkonsistentes Verhalten. Versuchen Sie Folgendes:
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
Erzwingt sed
in das Lesen der gesamten Datei als Zeile, erfasst alles und fügt es dann ein $total_repeats
wie oft.
Dies wird natürlich fehlschlagen, wenn Sie irgendwelche Nullzeichen in Ihrer Datei haben. Wählen Sie einen aus, von dem Sie wissen, dass er nicht vorhanden ist.
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
}
Das war's erstmal, Jungs, ich hoffe, diese willkürliche Antwort hat niemanden gestört. Ich habe sie alle viele Male getestet, aber ich bin nur ein zweijähriger Shell-Benutzer, also denken Sie daran, denke ich. Jetzt schlafen...
rm $tmp