最後のn行を除くすべてのファイルを印刷する(POSIXコマンドライン)方法はありますか? ユースケースとして、サイズが不明な複数のファイルがあり、そのすべてに削除したい既知のサイズのボイラープレート フッターが含まれています。自分で書く前に、これを行うユーティリティがすでにあるかどうか疑問に思っていました。
8 に答える
head(1)のほとんどのバージョン(特にGNUから派生していますが、BSDから派生していません)には、これを行う機能があります。印刷する行数に負の数を使用すると、ファイルの先頭(末尾を除く)が表示されます。
そのようです:
head -n -10 textfile
おそらく "wc" + "do the math" + "tail" メソッドよりも効率的ではありませんが、簡単に見ることができます:
tail -r file.txt | tail +NUM | tail -r
NUM
は、削除したい終了行の数よりも 1 多い場所です。たとえば、+11 は、最後の 10 行を除くすべてを出力します。head -n -NUM
これは、構文をサポートしていない BSD で機能します。
head
ユーティリティはあなたの友達です。
のマニュアルページからhead
:
-n, --lines=[-]K print the first K lines instead of the first 10; with the leading `-', print all but the last K lines of each file
これを行うための標準コマンドはありませんが、 awk または sed を使用してN行のバッファーを満たし、いっぱいになったら先頭から印刷できます。awk の例:
awk -v n=5 '{if(NR>n) print a[NR%n]; a[NR%n]=$0}' file
cat <filename> | head -n -10 # Everything except last 10 lines of a file
cat <filename> | tail -n +10 # Everything except 1st 10 lines of a file
フッターが他の場所に表示されない一貫した行で始まる場合は、次を使用できますsed
。
sed '/FIRST_LINE_OF_FOOTER/q' filename
これにより、フッターの最初の行が出力されます。それを避けたい場合:
sed -n '/FIRST_LINE_OF_FOOTER/q;p' filename
フッターのサイズが将来変更された場合、これは行数を数えるよりも堅牢になる可能性があります。(または、最初の行が変更されると、堅牢性が低下する可能性があります。)
head
システムのコマンドが をサポートしていない場合の別のオプションは、head -n -10
表示する行数を事前に計算することです。以下は、bash 固有の構文に依存します。
lines=$(wc -l < filename) ; (( lines -= 10 )) ; head -$lines filename
このhead -NUMBER
構文はhead
、下位互換性のために の一部のバージョンでサポートされていることに注意してください。POSIX はhead -n NUMBER
フォームのみを許可します。また、POSIX では、引数が-n
正の 10 進整数であることのみが許可されています。head -n 0
必ずしもノーオペレーションではありません。
POSIX 準拠のソリューションは次のとおりです。
lines=$(wc -l < filename) ; lines=$(($lines - 10)) ; head -n $lines filename
古い POSIX より前のシェルを扱う必要がある場合は、次のことを検討してください。
lines=`wc -l < filename` ; lines=`expr $lines - 10` ; head -n $lines filename
ファイルの長さが 10 行以下の場合、これらのいずれかが奇妙な動作をする可能性があります。
簡単です。回避したい行数に + を追加する必要があります。
この例では、最初の 9 行を除くすべての行が表示されます
tail -n +10 入力ファイル
(はい、最初の 10 ではありません...カウントが異なるため... 10 が必要な場合は、tail -n 11 inputfile と入力してください)