Linuxコマンド(catなど)で指定された数の文字を読み取る


120

catファイルから指定された数の文字を返すことができるLinuxのようなコマンドはありますか?

たとえば、次のようなテキストファイルがあります。

Hello world
this is the second line
this is the third line

そして、「こんにちは」という最初の5文字を​​返すようなものが欲しいです。

ありがとう


与えられた回答はどれもストリームからNバイトしか消費しないことに注意してください。例:永久に失われるmkfifo /tmp/test.fifo; echo "hello world">/tmp/test.fifo & head -c 5 /tmp/test.fifo消費もし" world\n"ます。
イエティ

回答:


192

head も動作します:

head -c 100 file  # returns the first 100 bytes in the file

..最初の100バイトを抽出して返します。

これを使用headすることの良い点は、tail一致の構文があることです。

tail -c 100 file  # returns the last 100 bytes in the file

これらを組み合わせてバイトの範囲を取得できます。たとえば、ファイルから2番目の 100バイトを取得するには、最初の200バイトを読み取り、headtailを使用して最後の100 バイトを取得します。

head -c 200 file | tail -c 100

@Miffy:最初の20バイトをheadで読み取り、次に使用tailして最後の10 バイトを取得します。例:head -c 20 file | tail -c 10
Dan

47

ddを使用して、バイトの任意のチャンクを抽出できます。

例えば、

dd skip=1234 count=5 bs=1

バイト1235から1239をその入力から出力にコピーし、残りを破棄します。

標準入力から最初の5バイトを取得するには、次のようにします。

dd count=5 bs=1

入力ファイル名を指定したい場合、ddには古い形式の引数解析があるので、次のようにします。

dd count=5 bs=1 if=filename

また、ddはそれが何をしたかを詳細に発表するので、それを捨てるには、次のようにします。

dd count=5 bs=1 2>&-

または

dd count=5 bs=1 2>/dev/null

2
dd bs=1ddは一度に1つの文字を読み書きするのでhead、countが大きい場合よりもはるかに遅いため、このソリューション一般にはお勧めしません。ただし、count = 5では目立ちません。
2008年

2
「dd count = 1 bs = 5」はどうですか?その場合、ヘッドは一度に5バイトを読み取ることになります。それでも、おそらく頭はより明確な解決策です。
Ben Combee 2008年

1
このおかげで、私は実際にバイナリファイルを「カット」する方法を探していましたdd
sdaau 2010年

これは効果的なアプローチをhead -c実装せずにbusyboxの命の恩人でしたdd bs=5 count=1
Jay Paroline

11

名前

head-ファイルの最初の部分を出力します

あらすじ

[ オプション ] ... [ ファイル ] ...

説明

各FILEの最初の10行を標準出力に出力します。複数のFILEがある場合、それぞれの前にファイル名を示すヘッダーを付けます。FILEがない場合、またはFILEが-の場合は、標準入力を読み取ります。

長いオプションへの必須の引数は、短いオプションでも必須です。
-c-- bytes = [-] N 各ファイルの最初のNバイトを出力します。先頭に「-」を付けて、各ファイルの最後のNバイトを除くすべてを出力します


3

頭や尾もそれを行うことができます:

頭-c X

ファイルの最初のXバイト(UTF-16ファイルの場合は必ずしも文字ではない)を出力します。最後のXバイトを除いて、テールも同じように動作します。

これは(そしてカットされて)移植可能です。


3
head -Line_number file_name | tail -1 |cut -c Num_of_chars

このスクリプトは、特定の行と場所からの正確な文字数を提供します。例:

head -5 tst.txt | tail -1 |cut -c 5-8

5行目の文字と5行目の5から8文字を与える

tail -1は、ヘッドによって表示される最後の行を選択するために使用されます。


2

行をgrepしてから、たとえば次のようにカットすることもできます。

grep 'text'ファイル名| カット-c 1-5


これは、入力ファイルが\ nのないエンドレスストリームである場合は機能しません
Ajay Brahmakshatriya

2

答えは6年前に尋ねられた質問への返信であることを知っています...

しかし、私は数時間同じようなものを探していて、それを発見しました 。cut-cはそれを正確に実行し、オフセットを指定することもできます。

cut -c 1-5Helloを返し、cut -c 7-11worldを返します。他のコマンドは必要ありません


2
あなたの右!。head -cは開始文字だけを読み、tail -cは最後の文字を読むのとは異なり、ファイルの中央からテキストを返すことができるより一般的な単一コマンドの可能性を強調したかっただけです。そして、grepを使用せずに:)。
bobbyus 2014年

2

これは数年前に回答/承認されましたが、現在承認されている回答は、iso-8859-1のような文字ごとの1バイトエンコーディング、または可変バイト文字セット(ラテン文字など)のシングルバイトサブセットに対してのみ正しいです。 UTF-8内)。代わりにマルチバイトスプライスを使用しても、UTF-16のような固定マルチバイトエンコーディングでのみ機能します。現在、UTF-8は一般的な標準になりつつあり、ネイティブスピーカーの数によるこの言語のリストと、ネイティブ/セカンダリの使用法による上位30言語のリストを見る、次の点を指摘することが重要です。単純な変数バイト文字に優しい(バイトベースではない)技術を用いてcut -cおよびtr/ sed文字クラスとします。

バイトと文字の問題に関するラテン語を中心とした2つの一般的な間違い/推測のために二重に失敗する次のものを比較します(1つは head vs. cut、は[a-z][A-Z]vs [:upper:][:lower:])。

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     head -c 1 | \
$     sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]

これに(注:これはFreeBSDではうまくいきましたが、両方とも cuttrGNU / Linux上でまだ台無しギリシャUTF-8での私のためにかかわらず):

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     cut -c 1 | \
$     tr '[:upper:]' '[:lower:]'
π

別のより最近の回答ではすでに「カット」が提案されていましたが、これは任意のオフセットを指定するために使用できるという副次的な問題のためであり、直接関連する文字とバイトの問題のためではありません。

もしあなたの cut-cが可変バイトエンコーディングを正しく処理しないは、「最初のX文字」(X数値で置き換える)を試すことができます。

  • sed -E -e '1 s/^(.{X}).*$/\1/' -e q -最初の行に限定されますが
  • head -n 1 | grep -E -o '^.{X}' -これは最初の行に限定され、2つのコマンドをチェーンしますが
  • dd -すでに他の回答で提案されていますが、本当に面倒です
  • sed複数行にまたがる文字を処理するためのスライディングウィンドウバッファーを備えた複雑なスクリプトですが、それはおそらく次のようなものを使用するよりも扱いにくい/壊れやすいです。dd

tr可変バイトエンコーディングで文字クラスを正しく処理しない場合は、次のことを試してください。

  • sed -E -e 's/[[:upper:]]/\L&/g (GNU固有)

申し訳ありませんが、ここでは機能しません... printf 'Πού ' | cut -c 1
意味不明

オンラインのドキュメントによると、まだ利用できません:「文字リストにリストされた位置にある文字のみを印刷するために選択してください。今のところ-bと同じですが、国際化によって変更されます。」[ gnu.org/software/coreutils/manual/html_node/...
レオ

@LEo 2番目のコメントのリンクに基づいて、GNUベースのOS、おそらくGNU / Linuxを使用しているようです。その場合、それは予想されます-私の回答の終わりにそれを述べます。FreeBSDでは(そしておそらく他のOSでも)動作しました(&動作します)が、GNU / Linuxでは動作しませんでした(まだ動作していません)。その場合、最後に代替方法について説明しました。私は個人的に、GNUツールセットがその点で他の人と同様に機能するために必要な国際化を行う自由な時間を誰かが見つけて志願するまで待つことができません。
rowanthorpe

0

次に、ここで説明したddアプローチを使用してラップする簡単なスクリプトを示します。

extract_chars.sh

#!/usr/bin/env bash

function show_help()
{
  IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}

e.g. 

2 10 /tmp/it     => extract chars 2-10 from /tmp/it
EOF
  "
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`

if [ -z "$3" ]
then
  dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
  dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null 
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.