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