Nudzę się, więc oto kilka innych metod łączenia pliku z samym sobą, głównie headza pomocą kuli. Wybacz mi, jeśli się nadmiernie tłumaczę, po prostu lubię mówić: P
Zakładając, Nże liczba samopodatków, które chcesz wykonać, i że Twój plik ma nazwę file.
Zmienne:
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)
Biorąc pod uwagę kopię filewywołanego file2, należy podać total_repeatsliczbę razy file, file2aby była taka sama, jak gdyby filebyła połączona z Nczasami.
Mówi się, że MATH jest tutaj mniej więcej: MATH (sedno)
To jest informatyka z pierwszego semestru, ale minęło trochę czasu, odkąd zrobiłem dowód indukcyjny, więc nie mogę się z tym pogodzić ... (również ta klasa rekurencji jest dość dobrze znana, 2^Loopswięc też ...)
POSIX
Używam kilku rzeczy, które nie są posiksowane, ale nie są one niezbędne. Do moich celów:
yes() { while true; do echo "$1"; done; }
Och, użyłem tylko tego. No cóż, sekcja jest już tutaj ...
Metody
head ze śledzeniem liczby linii.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Bez pliku tymczasowego, bez kota, jeszcze za dużo matematyki, cała radość.
teez MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Tutaj teejest czytanie ze filelecz wiecznie dołączając do niego, więc będzie zachować czytania pliku na powtórzeniu aż headzatrzymuje ją. I wiemy, kiedy to przerwać z powodu MATH . Dołączanie przesadza, więc użyłem pliku tymczasowego. Możesz również przyciąć nadmiar linii file.
evalwładca ciemności!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
To po prostu rozszerza się cat file file file ...i ewaluuje. Możesz to zrobić również bez $tmppliku:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
Drugie head„triki” catpolegające na umieszczeniu pośrednika między operacją a operacją zapisu. Możesz też oszukać catz innym, catale to ma niespójne zachowanie. Spróbuj tego:
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
Zmusza seddo odczytania całego pliku jako linii, przechwytuje go, a następnie wkleja $total_repeatswiele razy.
Nie powiedzie się to oczywiście, jeśli w pliku są znaki o wartości NULL. Wybierz taki, o którym wiesz, że go nie ma.
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
}
To wszystko na razie chłopaki, mam nadzieję, że ta arbitralna odpowiedź nikomu nie przeszkadzała. Testowałem je wszystkie wiele razy, ale jestem tylko dwuletnim użytkownikiem powłoki, więc myślę, że o tym myślę. Teraz spać ...
rm $tmp