UNIXでファイルの最後から2番目の行から文字を削除するにはどうすればよいですか?
たとえば、次のような内容のファイルがあります。
aaa
bbb*
ccc*
ddd*
eee
私の出力は次のようになります:
aaa
bbb*
ccc*
ddd
eee
これに関するアイデアはありますか?
sed を使用して 1 回のパスでこれを行う一般的な方法は、 GNU sed マニュアルで説明されているものと同様に、スライディング ウィンドウを使用することです。
最後から 2 番目の行の置換のみに関心があるため、ホールド スペースは必要ありません。この場合、単一N
で十分です:
sed 'N; $! { P; D; }; s/.\n/\n/'
または、BSD sed 互換スクリプトとして:
sed 'N; $! { P; D; }; s/.\n/\
/'
出力:
aaa
bbb*
ccc*
ddd
eee
説明
N
コマンドは、パターン スペースに 2 行目を追加します。$!
ブロックが評価されます。{ P; D; }
パターンスペースの最初の行を出力して削除します。パターン スペースが空でない場合、スクリプトを再起動するというD
副作用があります。頭に浮かぶ一般的なアプローチは 3 つあります。
wc -l file
行数を取得するために使用します。
awk 'NR==n-1{sub(/.$/,"")}1' n=$(wc -l file)
aaa
bbb*
ccc*
ddd
eee
ファイルを 2 回解析します。
awk 'FNR==NR{n++;next}FNR==n-1{sub(/.$/,"")}1' file file
aaa
bbb*
ccc*
ddd
eee
処理の前後でファイルを逆にします。
tac file | sed '2s/.$//' | tac
aaa
bbb*
ccc*
ddd
eee
awkで簡単:
awk '{a[NR]=$0}END{for(i=1;i<=NR;i++){if(i==NR-1)sub(/.$/,"",a[i]);print a[i]}}' file
awkで少しトリッキーな方法:
awk '{if(f>1)print p;p=l;f++;l=$0}END{sub(/.$/,"",p);print p;print l}' file