Mir ist langweilig. Hier sind ein paar weitere Methoden, wie man eine Datei an sich selbst head
ankettet, meistens mit einer Krücke. Verzeihen Sie mir, wenn ich mich selbst überfordere, ich sage gern Dinge: P
Angenommen, es N
ist die Anzahl der Selbstverkettungen, die Sie ausführen möchten und dass Ihre Datei einen Namen hat file
.
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)
Gegeben eine Kopie von file
angerufenen file2
, total_repeats
ist die Anzahl, file
wie oft hinzugefügt werden müsste file2
, um es so zu machen, als wäre file
es mit sich selbst verkettet N
worden.
Die besagte MATH ist mehr oder weniger hier: MATH (gist)
Es ist Informatiksachen des ersten Semesters, aber es ist schon eine Weile her, seit ich einen Induktionsbeweis gemacht habe, also kann ich nicht darüber hinwegkommen ... (Auch diese Rekursionsklasse ist ziemlich bekannt, 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, ich habe nur das benutzt. Na ja, 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, alle Freude.
tee
mit MATH
<file tee -a file | head -n $total_lines > $tmp cat $tmp > file
Hier tee
wird gelesen, file
aber ständig angefügt, so dass die Datei wiederholt gelesen wird, bis sie head
angehalten wird. Und wir wissen, wann wir es wegen MATH aufgeben müssen . Das Anhängen geht über Bord, also habe ich eine temporäre Datei verwendet. Sie könnten auch die überschüssigen Linien file
abschneiden.
eval
, der herr der dunkelheit!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp cat $tmp > file
Dies dehnt sich einfach aus cat file file file ...
und wertet es aus. Das geht auch ohne die $tmp
Datei:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" | head -n $((total_lines-linecount)) >> file
Der zweite head
"Trick", cat
indem ein mittlerer Mann zwischen ihm und dem Schreibvorgang platziert wird. Du könntest auch cat
mit einem anderen cat
überlisten, aber das hat inkonsistentes Verhalten. Versuche dies:
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 das sed
Lesen der gesamten Datei als Zeile, erfasst die gesamte Datei und fügt sie dann $total_repeats
mehrfach ein.
Dies wird natürlich fehlschlagen, wenn Ihre Datei Nullzeichen enthält. Wähle einen aus, von dem du weißt, dass er nicht da ist.
find_missing_char() { local file="$" 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 ist alles für jetzt Jungs, ich hoffe, diese willkürliche Antwort hat niemanden gestört. Ich habe sie alle viele Male getestet, aber ich bin nur zwei Jahre lang Shell-Benutzer. Denken Sie also daran, denke ich. Jetzt schlafen ...
rm $tmp