Mir ist langweilig, daher hier noch ein paar Methoden, wie man eine Datei mit sich selbst head
verknüpft , meistens als Krücke. Verzeihen Sie mir, wenn ich mich selbst übererkläre, ich sage einfach gerne Dinge: P
Angenommen, N
die 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 file
genannt file2
, total_repeats
ist die Anzahl der Male file
hinzugefügt werden müssten , file2
um es die als gleiche zu machen , wenn file
wurde mit sich selbst verkettet N
mal.
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.
tee
mit MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Hier tee
wird von gelesen, file
aber ständig angehängt, sodass die Datei bei Wiederholung so lange gelesen wird, bis sie head
angehalten 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 file
abschneiden.
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 $tmp
Datei 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 cat
mit einem anderen tricksen, cat
aber 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 sed
Lesen der gesamten Datei als Zeile, erfasst sie vollständig und fügt sie dann $total_repeats
mehrmals 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