GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Cara Memindahkan Garis Dalam File Teks Ke Atas Atau Ke Bawah Dengan Satu Baris?

Saya memiliki beberapa file teks, dan saya ingin dapat memindahkan garis arbitrer di salah satu file ke atas atau ke bawah satu baris (baris di awal atau akhir file akan tetap berada di tempatnya). Saya memiliki beberapa kode yang berfungsi tetapi tampaknya kludgy dan saya tidak yakin saya memiliki semua kasus Edge yang tercakup, jadi saya bertanya-tanya apakah ada beberapa alat atau paradigma yang melakukan ini dengan lebih baik (mis. saya dalam 6 bulan), lebih mudah di-debug, dan lebih mudah dirawat; “lebih efisien” tidak terlalu penting).

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
}

Saya dapat melakukan pemeriksaan kesalahan input di dalam atau di luar fungsi ini, tetapi poin bonus jika input yang buruk (seperti non-bilangan bulat, file yang tidak ada, atau nomor baris yang lebih besar dari panjang file) ditangani dengan baik.

Saya ingin itu berjalan dalam skrip Bash pada sistem Debian/Ubuntu modern. Saya tidak selalu memiliki akses root tetapi dapat mengharapkan alat "standar" untuk diinstal (pikirkan server web bersama), dan mungkin dapat meminta pemasangan alat lain jika saya dapat membenarkan permintaan tersebut (meskipun lebih sedikit ketergantungan eksternal selalu lebih baik).

Contoh:

$ 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
$ 

Jawaban yang Diterima:

Mirip dengan Archemar Sarannya, Anda dapat membuat skrip ini dengan ed :

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

yaitu

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

misalnya untuk pindah baris no. 21 satu baris:

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

untuk pindah baris no. 21 satu baris ke bawah:

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

Tetapi karena Anda hanya perlu memindahkan baris tertentu ke atas atau ke bawah satu baris, Anda juga bisa mengatakan bahwa Anda praktis ingin menukar dua baris berturut-turut. Temui sed :

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

yaitu

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

misalnya untuk pindah baris no. 21 satu baris:

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

untuk pindah baris no. 21 satu baris ke bawah:

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

Saya menggunakan gnu sed sintaks di atas. Jika portabilitas menjadi perhatian:

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

Selain itu, pemeriksaan biasa:file ada dan dapat ditulis; file_length > 2; line_no. > 1; line_no. < file_length;


Linux
  1. Cara Menambahkan Nomor Baris Ke File Teks Di Linux

  2. Bagaimana Cara Menyisipkan Teks Sebelum Baris Pertama Sebuah File?

  3. Bagaimana Menemukan Tanda Kurung yang Tak Tertandingi Dalam File Teks?

  1. Bagaimana Mengurai Setiap Baris File Teks Sebagai Argumen Untuk Perintah?

  2. Bagaimana cara mendaftar satu nama file per baris keluaran di Linux?

  3. Bagaimana melakukan sed like text ganti dengan python?

  1. Bagaimana cara menyalurkan panggilan subproses ke file teks?

  2. VIM:cara menuju ke baris yang tepat di Ubuntu

  3. Bagaimana cara menambahkan teks ke file?