53406

[code]

    #!/bin/bash
    
    TEST=`/bin/grep -w '^test' /tmp/test/test.txt`
    if [ "${TEST}" == "" ]; then
      #testがない場合
      echo "test" >> /tmp/test/test.txt
    else
      #testがある場合
    fi
    
[/code]

上記でファイルの最後にtest行が追加できたのですが、  
ファイルの最後からxx行目に追加するには echo ではできないでしょうか？


CC BY-SA 4.0
2019-03-13T13:56:08.797
53405
2019-06-09T22:53:01.127
12842
question
bash
bashでファイルの最後からxxx行目に行を追加したい


`echo`ではできないと思います。  
`sed`を使うとよいでしょう。

[code]

    file='/tmp/test/test.text'
    
    #ファイルの最後からxx行目の行番号を取得
    line_num=$(grep -c ^ $file)
    row_num=$((line_num - xx))
    
    #指定行に挿入
    sed -i ''$row_num'i test' $file
    
[/code]

細かなところは以下を参考にしました。

  * [grep -cで行数を数える時の罠](https://rcmdnk.com/blog/2017/04/20/computer-linux-mac-bash-zsh/)
  * [スクリプト言語sed、awk](http://www.coins.tsukuba.ac.jp/~yas/coins/syspro-2001/2001-06-25/)
  * [bashで演算を行う方法: 小粋空間](http://www.koikikukan.com/archives/2014/01/09-012345.php)


CC BY-SA 4.0
2019-03-13T14:50:38.987
53406
2019-03-13T14:50:38.987
12561
53405
answer


`sed`を使うのがスマートだと私も思いますが、別解として`head`と`tail`を使う方法を挙げてみます。

[code]

    #!/bin/bash
    set -Cu
    #set -vx # Uncomment for debugging
    
    FILE="/tmp/test/test.txt"
    TMPFILE="$(mktemp --tmpdir "tmp_XXXX_${0##*/}.XXXX")"
    TEST=$(/bin/grep -w '^test' $FILE)
    
    if [ "${TEST}" == "" ]; then
        #testがない場合最後から4行目に追記する
        #最終行の改行の有無によって結果が変わる点に注意する必要が有ります
        offset=4
        { 
            head --lines=$(($(wc --lines <"$FILE")-"$offset")) "$FILE"
            echo "test"
            tail --lines="$offset" "$FILE"
        } >"$TMPFILE"
        mv --force "$TMPFILE" "$FILE"
    else
        #testがある場合
        : 
    fi
    
    exit $?
    
[/code]


CC BY-SA 4.0
2019-03-14T02:55:43.377
53419
2019-03-14T02:55:43.377
25936
53405
answer


sedで末尾行から何行目に挿入、というのは難しいですが、先頭行から何行目に挿入、というのは簡単なので一度逆転させてみました。

[code]

    FILE=hoge.txt
    NUM=5
    tac "${FILE}" | sed "${NUM}i test" | tac
    
[/code]


CC BY-SA 4.0
2019-06-09T22:53:01.127
55657
2019-06-09T22:53:01.127
34583
53405
answer