Mir ist langweilig, daher hier noch ein paar Methoden, wie man eine Datei mit sich selbst headverknüpft , meistens als Krücke. Verzeihen Sie mir, wenn ich mich selbst übererkläre, ich sage einfach gerne Dinge: P
Angenommen, Ndie Anzahl der Selbstverkettungen, die Sie ausführen möchten, und der Name Ihrer Datei 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)
In Anbetracht der eine Kopie filegenannt file2, total_repeatsist die Anzahl der Male filehinzugefügt werden müssten , file2um es die als gleiche zu machen , wenn filewurde mit sich selbst verkettet Nmal.
Said MATH is here, mehr oder weniger: MATH
Es ist erst ein Semester Informatik, aber es ist schon eine Weile her, dass ich einen Induktionsnachweis gemacht habe, damit ich nicht darüber hinwegkomme 2^Loops...
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. Na ja, der Abschnitt ist schon da ...
Methoden
head mit Zählerverfolgung.
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.
teemit MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Hier teewird von gelesen, fileaber ständig angehängt, sodass die Datei bei Wiederholung so lange gelesen wird, bis sie headangehalten wird. Und wir wissen, wann wir es wegen MATH beenden müssen . Das Anhängen geht über Bord, also habe ich eine temporäre Datei verwendet. Sie könnten auch die überschüssigen Linien fileabschneiden.
eval, der Herr der Dunkelheit!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Dies wird einfach erweitert cat file file file ...und ausgewertet. Sie können dies auch ohne die $tmpDatei tun :
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
Der zweite head"Trick" besteht darin cat, einen Zwischenmenschen zwischen den Schreibvorgang zu setzen. Sie könnten auch catmit einem anderen tricksen, cataber das hat ein 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 sedLesen der gesamten Datei als Zeile, erfasst sie vollständig und fügt sie dann $total_repeatsmehrmals ein.
Dies schlägt natürlich fehl, wenn Ihre Datei Nullzeichen enthält. Wählen Sie einen aus, von dem Sie wissen, dass er nicht da 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 ist alles, Jungs, ich hoffe, diese willkürliche Antwort hat niemanden gestört. Ich habe sie alle oft getestet, aber ich bin nur ein zweijähriger Shell-Benutzer. Denken Sie also daran, denke ich. Jetzt schlafen ...
rm $tmp