あなたがtxtファイルを持っているとしましょう、ファイルの上位10行と下位10行を同時に表示するコマンドは何ですか?
つまり、ファイルの長さが200行の場合は、1行目から10行目と190〜200行目を一度に表示します。
あなたがtxtファイルを持っているとしましょう、ファイルの上位10行と下位10行を同時に表示するコマンドは何ですか?
つまり、ファイルの長さが200行の場合は、1行目から10行目と190〜200行目を一度に表示します。
回答:
あなたは簡単にできます:
(head; tail) < file.txt
そして、何らかの理由でパイプを使用する必要がある場合は、次のようにします。
cat file.txt | (head; tail)
注:file.txtの行数が先頭のデフォルトの行+末尾のデフォルトの行よりも小さい場合、重複した行が印刷されます。
head
の最初の10行を消費した後のストリームの末尾は提供します。(これをhead < file.txt; tail < file.txt
20行未満のファイルと比較してください)。覚えておくべき非常にマイナーなポイント。(ただし、+ 1のままです)
head
のみ表示され、入力の最初の10行は、全くそれがなかったことが保証されていない消費少ない入力のために残して、終わる10行を見つけるために、よりそれをless
表示します。
seq 100 | (head; tail)
最初の10個の数字だけを与えます。はるかに大きな入力サイズ(のようなseq 2000
)でのみ、尾は何らかの入力を受け取ります。
純粋なストリーム(コマンドからの出力など)の場合、 'tee'を使用してストリームをフォークし、1つのストリームを先頭に、もう1つを末尾に送信できます。これには、bashの「>(list)」機能(+ / dev / fd / N)を使用する必要があります。
( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )
または/ dev / fd / N(または/ dev / stderr)とサブシェルを使用して複雑なリダイレクトを行う:
( ( seq 1 100 | tee /dev/fd/2 | head 1>&3 ) 2>&1 | tail ) 3>&1
( ( seq 1 100 | tee /dev/stderr | head 1>&3 ) 2>&1 | tail ) 3>&1
(これらはどちらもcshまたはtcshでは機能しません。)
もう少し良い制御を行うには、次のperlコマンドを使用できます。
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
修正:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
とtail
コマンドの間の順序付けは保証されていません:\ ...
head -10 file.txt; tail -10 file.txt
それ以外に、独自のプログラム/スクリプトを作成する必要があります。
cat
しhead
たりtail
パイプしたりしてきました。それらを個別に使用できることを知って嬉しいです!
{ head file; tail file; } | prog
必要はあり
JFセバスチャンのコメントに基づく:
cat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1
このように、1つのパイプで最初の行と残りの行を別々に処理できます。これは、CSVデータの操作に役立ちます。
{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
N * 2 2 4 6
ここでの問題は、ストリーム指向のプログラムがファイルの長さを事前に知らないことです(実際のストリームの場合、ファイルの長さが存在しない可能性があるため)。
tail
最後に見たn行をバッファリングし、ストリームの終わりを待ってから印刷するようなツール。
これを単一のコマンドで実行したい場合(およびオフセットを使用して動作させ、重複している場合は行を繰り返さないようにする場合)、前述のこの動作をエミュレートする必要があります。
このawkを試してください:
awk -v offset=10 '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile
a.out | awk -v ...
このソリューションで終わるまでにはかなりの時間がかかりましたが、これはすべてのユースケース(これまでのところ)をカバーした唯一のソリューションと思われます。
command | tee full.log | stdbuf -i0 -o0 -e0 awk -v offset=${MAX_LINES:-200} \
'{
if (NR <= offset) print;
else {
a[NR] = $0;
delete a[NR-offset];
printf "." > "/dev/stderr"
}
}
END {
print "" > "/dev/stderr";
for(i=NR-offset+1 > offset ? NR-offset+1: offset+1 ;i<=NR;i++)
{ print a[i]}
}'
機能リスト:
私はこの解決策をしばらく探していました。sedを使って自分で試してみましたが、ファイル/ストリームの長さが事前にわからないという問題は解決できませんでした。上記で利用可能なすべてのオプションの中で、私はCamille Goudeseuneのawkソリューションが好きです。彼の解決策では、出力に十分に小さいデータセットを含む余分な空白行が残っていることに注意しました。ここでは、余分な行を削除する彼のソリューションの変更を提供します。
headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }' ; }
file.extの最初の10行、次に最後の10行:
cat file.ext | head -10 && cat file.ext | tail -10
ファイルの最後の10行、次に最初の10行:
cat file.ext | tail -10 && cat file.ext | head -10
次に、出力を他の場所にパイプすることもできます。
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
tail
、head
または関数に渡すbashスクリプトの記述を伴います。
これを行う簡単なpythonアプリを作成しました:https : //gist.github.com/garyvdm/9970522
パイプ(ストリーム)とファイルを処理します。
パイプ(ストリーム)とファイルを処理するには、これを.bashrcまたは.profileファイルに追加します。
headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' ; }
その後、あなたはできません
headtail 10 < file.txt
だけでなく
a.out | headtail 10
(これは、普通のとは異なり、10が入力の長さを超えた場合でも偽の空白行を追加しますa.out | (head; tail)
。以前の回答者に感謝します。)
注:headtail 10
ではありませんheadtail -10
。
ファイルの最初の10行と最後の10行を印刷するには、次のようにします。
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
sed -n "1,10p; $(( $(wc -l ${aFile} | grep -oE "^[[:digit:]]+")-9 )),\$p" "${aFile}"
注:aFile変数には、ファイルの完全パスが含まれています。
ファイルのサイズによっては、その内容を積極的に読み込むことが望ましくない場合があります。そのような状況では、単純なシェルスクリプトで十分です。
これが、私が分析していた非常に大きなCSVファイルの数について、私が最近これをどのように処理したかです。
$ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done
これにより、各ファイルの最初の10行と最後の10行が出力され、その前後にファイル名と省略記号も出力されます。
単一の大きなファイルの場合、次のコマンドを実行するだけで同じ効果が得られます。
$ head somefile.csv && echo ... && tail somefile.csv