GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux-Befehl, um eine Datei n-mal mit sich selbst zu verketten

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ühren
for 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


Linux
  1. Linux-wc-Befehl

  2. Linux grep-Befehl

  3. Linux-Cat-Befehl

  4. 14 Nützliche „cat“-Befehlsbeispiele in Linux

  5. file Befehlsbeispiele in Linux

Gzip-Befehl unter Linux

Gunzip-Befehl unter Linux

Stat-Befehl unter Linux

10 Beispiele für Linux-Cat-Befehle für Anfänger

Verwenden des Cat-Befehls unter Linux mit Beispielen

Linux cat-Befehlsbeispiele