シェル組み込み関数

シェル組み込み関数

(UTF-8でエンコードされた)テキストファイルを特定の文字数に切り捨てるには?行の長さは関係なく、単語の途中にカットがあってもいいです。

  • cut1行ずつ作業しているようですが、完全なファイルが必要です。
  • head -c文字以外のバイトを使用してください。

ベストアンサー1

一部のシステムには、複数のtruncateファイルを切り捨てるコマンドがあります。バイト(文字ではありません)。

perlほとんどのシステムにデフォルトでインストールされている文字を使用できますが、2つ以上の文字に切り捨てられる内容はありません。

真珠

perl -Mopen=locale -ne '
  BEGIN{$/ = \1234} truncate STDIN, tell STDIN; last' <> "$file"
  • の場合、-Mopen=localeロケールの文字概念を使用します(したがって、UTF-8文字セット、つまりUTF-8エンコーディング文字を使用するロケールで)。-CSロケールの文字セットに関係なく、I / OをUTF-8にデコード/エンコードするには、に置き換えます。

  • $/ = \1234:レコード区切り文字を整数への参照として設定します。これは固定長レコード(単位数)を指定する方法です。数値)。

  • 次に、最初のレコードを読み取った後、stdinを所定の位置で切り取り(最初のレコードの終わりに)終了します。

GNU sed

GNUを使用すると、sed次のことができます。 (ファイルにNUL文字や有効な文字を形成しないバイトシーケンスが含まれていないと仮定する場合 - 両方ともテキストファイルに対応する必要があります。)

sed -Ez -i -- 's/^(.{1234}).*/\1/' "$file"

ただし、これはファイル全体を読み取り、メモリに保存してから新しいコピーを書き込むため、はるかに効率的ではありません。

GNU awk

GNUと同じawk

awk -i /usr/share/awk/inplace.awk -v RS='^$' -e '
  {printf "%s", substr($0, 1, 1234)}' -E /dev/null "$file"
  • -e code -E /dev/null "$file"任意のファイル名を渡す方法です。gawk
  • RS='^$':喫煙モード

使用しないでください-i inplace現在の作業ディレクトリから最初に拡張機能をgawkロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

シェル組み込み関数

ksh93bashまたは使用(コンテンツにNUL​​バイトが含まれていないと仮定し、zshExcept以外のシェルを使用):zsh

content=$(cat < "$file" && echo .) &&
  content=${content%.} &&
  printf %s "${content:0:1234}" > "$file"

そしてzsh

read -k1234 -u0 s < $file &&
  printf %s $s > $file

または:

zmodload zsh/mapfile
mapfile[$file]=${mapfile[$file][1,1234]}

そしてksh93またはbash(参考複数のバージョンのマルチバイト文字で偽でした。bash):

IFS= read -rN1234 s < "$file" &&
  printf %s "$s" > "$file"

ksh93<>;リダイレクト演算子を使用してファイルを書き換えるのではなく、その場所からファイルを切り捨てることもできます。

IFS= read -rN1234 0<>; "$file"

アイコン+ヘッダ

到着印刷UTF32BE最初の1234文字の場合は、/など、文字ごとに固定バイト数を使用するエンコードに変換することも別のオプションですUCS-4

iconv -t UCS-4 < "$file" | head -c "$((1234 * 4))" | iconv -f UCS-4

head -c標準ではありませんが、かなり一般的です。標準に対応するのは、dd bs=1 count="$((1234 * 4))"一度に1バイトを読み、一度に1バイトを書き込むため、効率が悪くなります。iconv標準コマンドですが、エンコード名は標準化されていないため、システムがそうでない可能性があります。UCS-4

ノート

いずれにせよ、出力は最大1234文字まで可能ですが、区切りのない行で終わることができるため、有効なテキストではない可能性があります。

さらに、これらの解決策は文字の中央にあるテキストを切り捨てませんが、文字の中央にあるテキストを破ることができます。文字たとえば、éU + 0065 U + 0301(aeの後に鋭いアクセントの組み合わせ)、または分解された形式の韓国語の音節文字で表されます。


bs1 およびパイプ入力では、GNU 拡張を使用しない限り、1 以外の値は安定して使用できません。パイプを埋めることができるよりもパイプをより早く読み取れば短い読み取りが可能だからiflag=fullblockです。ddiconv

おすすめ記事