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

Wie verschiebt man eine Zeile in einer Textdatei um eine Zeile nach oben oder unten?

Ich habe einige Textdateien und möchte diese verschieben können eine beliebige Zeile in einer der Dateien eine Zeile nach oben oder unten (Zeilen am Anfang oder Ende der Datei würden dort bleiben, wo sie sind). Ich habe etwas funktionierenden Code, aber er scheint klumpig zu sein, und ich bin nicht überzeugt, dass ich alle Grenzfälle abgedeckt habe, also frage ich mich, ob es ein Tool oder Paradigma gibt, das dies besser macht (z. B. den Code leichter zu verstehen (für andere Leser oder ich in 6 Monaten), einfacher zu debuggen und einfacher zu warten; „effizienter“ ist nicht sehr wichtig).

move_up() {
  # fetch line with head -<line number> | tail -1
  # insert that one line higher
  # delete the old line
  sed -i -e "$((line_number-1))i$(head -$line_number $file | tail -1)" -e "${line_number}d" "$file"
}

move_down() {
  file_length=$(wc -l < "$file")
  if [[ "$line_number" -ge $((file_length - 1)) ]]; then
    # sed can't insert past the end of the file, so append the line
    # then delete the old line
    echo $(head -$line_number "$file" | tail -1) >> "$file"
    sed -i "${line_number}d" "$file"
  else
    # get the line, and insert it after the next line, and delete the original
    sed -i -e "$((line_number+2))i$(head -$line_number $file | tail -1)" -e "${line_number}d" "$file"
  fi
}

Ich kann Eingaben innerhalb oder außerhalb dieser Funktionen auf Fehler überprüfen, aber Bonuspunkte, wenn fehlerhafte Eingaben (wie nicht ganze Zahlen, nicht vorhandene Dateien oder Zeilennummern, die größer als die Länge der Datei sind) vernünftig behandelt werden.

Ich möchte, dass es in einem Bash-Skript auf modernen Debian/Ubuntu-Systemen ausgeführt wird. Ich habe nicht immer Root-Zugriff, kann aber erwarten, dass „Standard“-Tools installiert werden (denken Sie an einen gemeinsam genutzten Webserver), und kann in der Lage sein, die Installation anderer Tools anzufordern, wenn ich die Anfrage rechtfertigen kann (obwohl weniger externe Abhängigkeiten immer besser sind).

Beispiel:

$ cat b
1
2
3
4
$ file=b line_number=3 move_up
$ cat b
1
3
2
4
$ file=b line_number=3 move_down
$ cat b
1
3
4
2
$ 

Akzeptierte Antwort:

Ähnlich wie Archemar ’s Vorschlag, Sie könnten dies mit ed skripten :

printf %s\n ${linenr}m${addr} w q | ed -s infile

d.h.

linenr                      #  is the line number
m                           #  command that moves the line
addr=$(( linenr + 1 ))      #  if you move the line down
addr=$(( linenr - 2 ))      #  if you move the line up
w                           #  write changes to file
q                           #  quit editor

z.B. Zeile Nr. verschieben 21 eine Zeile nach oben:

printf %s\n 21m19 w q | ed -s infile

Zeile Nr. verschieben 21 eine Zeile tiefer:

printf %s\n 21m22 w q | ed -s infile

Da Sie aber eine bestimmte Zeile nur um eine Zeile nach oben oder unten verschieben müssen, könnte man auch sagen, dass Sie praktisch zwei aufeinanderfolgende Zeilen vertauschen möchten. Lernen Sie sed kennen :

sed -i -n 'addr{h;n;G};p' infile

d.h.

addr=${linenr}           # if you move the line down
addr=$(( linenr - 1 ))   # if you move the line up
h                        # replace content of the hold  buffer with a copy of the pattern space
n                        # read a new line replacing the current line in the pattern space  
G                        # append the content of the hold buffer to the pattern space
p                        # print the entire pattern space

z.B. Zeile Nr. verschieben 21 eine Zeile nach oben:

sed -i -n '20{h;n;G};p' infile

Zeile Nr. verschieben 21 eine Zeile tiefer:

sed -i -n '21{h;n;G};p' infile

Ich habe gnu sed verwendet Syntax oben. Wenn Portabilität ein Problem darstellt:

sed -n 'addr{
h
n
G
}
p' infile

Ansonsten werden die üblichen Prüfungen durchgeführt:Datei existiert und ist beschreibbar; file_length > 2; line_no. > 1; line_no. < file_length;


Linux
  1. Wie fügt man Text vor der ersten Zeile einer Datei ein?

  2. Wie finde ich nicht übereinstimmende Klammern in einer Textdatei?

  3. Wie analysiert man jede Zeile einer Textdatei als Argument für einen Befehl?

  4. Wie bewegt man sich ein Verzeichnis nach unten?

  5. VIM:wie man unter Ubuntu zur genauen Zeile geht

So verschieben Sie eine Datei unter Linux

So lesen Sie Dateien Zeile für Zeile in Bash

So fügen Sie unter Linux Text an das Dateiende an

So lesen Sie eine Datei Zeile für Zeile in Bash

So berühren Sie eine Datei und mkdir bei Bedarf in einer Zeile

Wie füge ich mit sed Text in die erste Zeile einer Datei ein?