GNU/Linux >> Linux の 問題 >  >> Linux

テキストファイルの行を1行上または下に移動するにはどうすればよいですか?

テキストファイルがいくつかありますが、移動できるようにしたいと思います。 1行上または下のファイルの任意の行(ファイルの最初または最後の行はそのままになります)。私はいくつかの動作するコードを持っていますが、それは厄介なようで、すべてのエッジケースをカバーしているとは確信していません。したがって、これをよりよく行うツールまたはパラダイムがあるかどうか疑問に思っています(たとえば、コードをより理解しやすい(他の読者または私は6か月で)、デバッグが簡単で、保守も簡単です。「より効率的」はそれほど重要ではありません。

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
}

これらの関数の内外で入力のエラーチェックを行うことはできますが、不正な入力(整数でない、存在しないファイル、ファイルの長さを超える行番号など)の場合のボーナスポイントは適切に処理されます。

最新のDebian/UbuntuシステムでBashスクリプトで実行したい。私は常にルートアクセス権を持っているわけではありませんが、「標準」ツールがインストールされることを期待できます(共有ウェブサーバーを考えてください)。 リクエストを正当化できる場合は、他のツールのインストールをリクエストできます(ただし、外部の依存関係は少ない方が常に優れています)。

例:

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

承認された回答:

Archemarに似ています の提案、これをedでスクリプト化できます :

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

つまり、

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

例えば行番号を移動します。 21 1つのラインナップ:

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

行番号を移動します。 21 1行下:

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

ただし、特定の行を1行上または下に移動するだけでよいので、実際には2つの連続する行を入れ替えたいと言うこともできます。 sedに会う :

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

つまり、

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

例えば行番号を移動します。 21 1つのラインナップ:

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

行番号を移動します。 21 1行下:

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

gnu sedを使用しました 上記の構文。移植性が懸念される場合:

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

それ以外は、通常のチェック:ファイルが存在し、書き込み可能です。 file_length > 2; line_no. > 1; line_no. < file_length;


Linux
  1. Linuxでテキストファイルに行番号を追加する方法

  2. ファイルの最初の行の前にテキストを挿入する方法は?

  3. テキストファイルで一致しない角かっこを見つける方法は?

  1. Linux でヘッダーとトレーラー行をファイルに追加する方法

  2. Linux で出力行ごとに 1 つのファイル名をリストするにはどうすればよいですか?

  3. sed のようなテキストを python に置き換えるにはどうすればよいですか?

  1. サブプロセス呼び出しをテキスト ファイルにパイプするにはどうすればよいですか?

  2. ファイルにテキストを追加するにはどうすればよいですか?

  3. 1 つのテキスト ファイルを複数の *.txt ファイルに分割する方法は?