最小文字数の行を見つける方法


22

一般的なUNIXコマンドを使用して、シェルスクリプトを作成しています。文字数が最も少ない行(空白を含む)を取得する必要があります。最大で約20行あります。

head -$L | tail -1 | wc -m行Lの文字カウントを見つけるために使用できることを知っています。問題は、それを使用して考えることができる唯一の方法は、ifステートメントの混乱を手動で記述して値を比較することです。

サンプルデータ:

seven/7
4for
8 eight?
five!

4forその行の文字が最も少ないため、戻ります。

私の場合、複数の行の長さが最も短い場合、単一の行が返されます。最小の長さであれば、どちらを選択してもかまいません。しかし、私は、他の状況にいる他のユーザーに両方の方法を示すことに害はないと思います。


5
長さが4の複数の行がある場合はどうなりますか?それらも印刷する必要がありますか?
カオス

私の場合、複数の行の長さが最も短い場合は、単一の行が返されます。最小の長さであれば、どちらを選択してもかまいません。しかし、私は、他の状況にいる他のユーザーに両方の方法を示すことに害はないと思います。
マシューD.ショールフィールド

回答:


13

Perlの方法。同じ最短の長さの行が多数ある場合、この方法ではそのうちの1つだけが出力されることに注意してください。

perl -lne '$m//=$_; $m=$_ if length()<length($m); END{print $m if $.}' file 

説明

  • perl -lne-n「入力ファイルを1行-lずつ読み込む」ことを意味し、後続の改行を各入力行から削除し、改行を各print呼び出しに追加します。そして-e、各行に適用されるスクリプトです。
  • $m//=$_:定義されていない限り$m、現在の行($_)に設定し$mます。この//=演算子はPerl 5.10.0以降で使用可能です。
  • $m=$_ if length()<length($m):現在の値の$m長さが現在の行の長さより大きい場合、現在の行($_)をとして保存し$mます。
  • END{print $m if $.}:すべての行が処理されたら、現在の値で$mある最短行を出力します。これif $.により、行番号($.)が定義されている場合にのみこれが発生し、空白入力のために空行が印刷されるのを防ぎます。

または、ファイルがメモリに収まるほど小さいため、次のことができます。

perl -e '@K=sort{length($a) <=> length($b)}<>; print "$K[0]"' file 

説明

  • @K=sort{length($a) <=> length($b)}<>:これ<>は、要素がファイルの行である配列です。sortその長さに応じてそれらを分類し、ソートされた行は配列として保存されます@K
  • print "$K[0]":配列の最初の要素@K:最短行を出力します。

すべての最短行を印刷する場合は、次を使用できます。

perl -e '@K=sort{length($a) <=> length($b)}<>; 
         print grep {length($_)==length($K[0])}@K; ' file 

1
-Cバイト数ではなく文字数で長さを測定するために追加します。UTF-8ロケールで$$は、バイト数は(2対3)より少なくなりますが、文字数は多くなります(2対1)。
ステファンシャゼル

17

sqlite3

sqlite3 <<EOT
CREATE TABLE file(line);
.import "data.txt" file
SELECT line FROM file ORDER BY length(line) LIMIT 1;
EOT

これはここで私のお気に入りであり、SQLを考えたことはありません
カオス

2
これはコードステータスの賢いコードです
シャドウトーカー

2
これにより、ファイル全体がメモリに読み込まれ、2つ目のディスク上のコピーが作成されますか?もしそうなら、それは賢いですが非効率的です。
ジョンクーゲルマンはモニカをサポートします

1
@JohnKugelmanこれはおそらく、4行全体を一時メモリのみのデータベースに吸収します(それがstrace示すものです)。本当に大きなファイルで作業する必要がある場合(システムがスワップしない場合)、ファイル名を追加するだけで強制的に実行できsqlite3 $(mktemp)、すべてのデータがディスクに書き込まれます。
FloHimself

次のエラーが表示されます: "" "xaa:8146:エスケープされていない"文字 "" "および" "" xaa:8825:期待される1列ですが、2-余分なものは無視されました "" "。 。
Ahmedov

17

以下awkは、最初に見つかった最小行を印刷するためのソリューションの変形です。

awk '
  NR==1 || length<len {len=length; line=$0}
  END {print line}
'

1つの条件で単純に拡張して、すべての最小行を印刷できます。

awk '
  length==len {line=line ORS $0}
  NR==1 || length<len {len=length; line=$0}
  END {print line}'
'

12

Pythonはかなり簡潔になり、コードはTinで何を言っているかを示しています。

python -c "import sys; print min(sys.stdin, key=len),"

最後のコンマはあいまいです、私は認めます。printステートメントが追加の改行を追加するのを防ぎます。さらに、次のような0行をサポートするPython 3でこれを書くことができます。

python3 -c "import sys; print(min(sys.stdin, key=len, default='').strip('\n'))"


錫は何と言っていますか?
mikeserv

@mikeserve:「lenをキーとして使用してsys.stdinの最小値を出力します」;
スティーブジェソップ

1
ああ。バイナリサイズ、依存関係のクリープ、実行時間については何もありませんか?
mikeserv

2
@mikeserv:いいえ、小さな文字はブリキの上にありません。それは、「ヒョウに注意してください」とマークされたドアの後ろの、施錠されたファイリングキャビネットの地下室にある勧告リーフレットにあります。
スティーブジェソップ

落とし穴- ディスプレイ上など。
mikeserv

10

私はいつも純粋なシェルスクリプト(execはありません!)を使用したソリューションが大好きです。

#!/bin/bash
min=
is_empty_input="yes"

while IFS= read -r a; do
    if [ -z "$min" -a "$is_empty_input" = "yes" ] || [ "${#a}" -lt "${#min}" ]; then
        min="$a"
    fi
    is_empty_input="no"
done

if [ -n "$a" ]; then
    if [ "$is_empty_input" = "yes" ]; then
        min="$a"
        is_empty_input="no"
    else
        [ "${#a}" -lt "${#min}" ] && min="$a"
    fi
fi

[ "$is_empty_input" = "no" ] && printf '%s\n' "$min"

入力のNULバイトに問題があります。したがって、の代わりにprintf "ab\0\0\ncd\n" | bash this_script印刷しabますcd


これは本当に最も純粋です。ただし、テストの不器用さは、代わりにbash中間結果をパイプするように私を説得するでしょうsort
オリオン

2
あなたのノーエグゼクティブをベンチしようとしましたかソリューションと他のソリューション execのパフォーマンスの違いを比較します!そして幹部なし!同様の問題の解決策。スパイダーの場合- var=$(get data)データフローを単一のコンテキストに制限するためなどの形式で- ストリームで-パイプラインを介してデータ移動する場合- 個別のプロセスを実行することは非常にまれです必要な場合にのみモジュール式プログラムを適用します。
mikeserv

1
@DigitalTrauma-拡張された連続した数字列は、他の拡張文字列よりもシェルクォートを必要とする条件から多かれ少なかれ除外されません。多くのシェルは事前に設定された環境設定を受け入れ$IFSますが、デフォルト$IFS値に何もない場合でも、数字を区別しません$IFS。したがって、それは特に信頼できるデフォルトではありません。
mikeserv


1
コメントと賛成票をありがとうございました(担当者の一部は私の答えを修正するために@cuonglmに行くべきです)。一般に、純粋なシェルスクリプトを毎日練習することを他の人に勧めることはありませんが、そのスキルは、静的リンク以外に/bin/sh利用できない極端な状況で非常に役立つことがわかります。SunOS4ホストが/usr紛失したり.so破損したりしたことが何度かありましたが、現在のLinux時代では、組み込みシステムや起動に失敗したシステムのinitrdで同様の状況が時々発生します。BusyBoxは、最近取得したすばらしいものの1つです。
八重ashi

9

ここに純粋なzsh解決策があります(最小の長さですべての行を印刷しますfile):

IFS=$'\n'; print -l ${(M)$(<file):#${~${(o@)$(<file)//?/?}[1]}}

入力例:

seven/7
4for
8 eight?
five!
four

出力は次のとおりです。

4for
four

簡単な説明が必要だと思います:-)


まず、内部フィールドセパレーターを改行に設定します。

IFS=$'\n';

これまでのところ、今は難しい部分です。フラグをprint使用して-l、スペースではなく改行で区切られた結果を出力します。

さて、内部から始めます。

$(<file)

ファイルは1行ずつ読み取られ、配列として扱われます。次に:

${(o@)...//?/?}

oフラグは、結果は、昇順で注文されるべきであると述べている@、あまりにも配列として結果を治療するための手段を。(//?/?)の後ろの部分は、すべての文字を?。今:

${~...[1]}

最初の配列要素を取得[1]します????。これは最も短く、あなたの場合はnow です。

${(M)$(<file):#...}

一致は各配列要素で個別に実行され、一致しない配列要素は削除されます(M)。一致する各要素????(4文字)は配列に残ります。そのため、残りの要素は4文字(最短)の要素です。

編集:最短行の1つだけが必要な場合、この修正版は最初の行を出力します。

IFS=$'\n'; print -l ${${(M)$(<file):#${~${(o@)$(<file)//?/?}[1]}}[1]}

8
tr -c \\n 1 <testfile |   #first transform every [^\n] char to a 1
grep -nF ''           |   #next get line numbers
paste -d: - testfile  |   #then paste it together with itself
sort  -t: -nk2,2          #then sort on second field

...そして勝者は... 2行目です。

2:1111:4for
4:11111:five!
1:1111111:seven/7
3:11111111:8 eight?

しかし、それに関する問題は、すべての行が機能するために長さが2倍以上でなければならないことです。そのため、LINE_MAXは事実上半分になります。原因は、ベース1を使用していることです。-線の長さを表すため。同様の、そしておそらくもっときちんとしたアプローチは、ストリーム内のその情報を圧縮することです。私に起こるそれらの線に沿った最初のアイデアは、私がそれにすべきだというunexpandことです:

tr -c \\n \  <testfile    |   #transform all [^\n] to <space>
unexpand -t10             |   #squeeze every series of 10 to one tab
grep -nF ''               |   #and get the line numbers
sed    's/:/!d;=;:/;h;:big    #sed compares sequential lines
$P;$!N; /\(:[^ ]*\)\( *\)\n.*\1.*\2/!D     #newest line is shorter or...
        g;/:./!q;b big'   |   #not; quit input entirely for blank line
sed -f - -e q testfile        #print only first occurrence of shortest line

それは印刷します...

2
4for

もう一つ、ちょうどsed

sed -n '/^\n/D;s/\(.\)\(\n.*\)*/\1/g
$p;h;   s// /g;G;x;n;//!g;H;s// /g
G;      s/^\( *\)\(\n \1 *\)\{0,1\}\n//
D'      <infile >outfile

構文は標準に準拠していますが、古いsedものが\(reference-group\)\{counts\}正しく処理されるという保証はありません-多くはそうではありません。

基本的に、同じ正規表現を繰り返し入力に適用します。これは、コンパイルするときに非常に有益です。そのパターンは次のとおりです。

\(.\)\(\n.*\)*

異なる方法で異なる文字列に一致します。例えば:

string1\nstring2\nstring3

... sin \1および''null文字列in と一致します\2

1\nstring2\nstring3

... 1in \1および\nstring2\nstring3in と一致\2

\nstring2\nstring3

... \nin \1および''null文字列in と一致します\2\nパターンスペースの先頭でewlineが発生する可能性がある場合、これは問題/^\n/Dになり//!gますが、これを防ぐために、およびコマンドが使用されます。私は使用しまし[^\n]たが、この小さなスクリプトの他のニーズにより移植性が懸念され、多くの誤った解釈の方法に満足しませんでした。さらに、.高速です。

\nstring2
string1

...に一致し\ns再度入力する\1と、両方で''NULL文字列が取得され\2ます。空の行はまったく一致しません。

パターンが部分的に適用されるg、2つのバイアス(左端の標準バイアスと右端の右の\nユーラインバイアスの両方)が相殺され、スキップが実行されます。いくつかの例:

s/\(.\)\(\n.*\)*/\1:\2/g
s/\(.\)\(\n.*\)*/\2\1:/g
s/\(.\)\(\n.*\)*/\1: /g
s/\(.\)\(\n.*\)*/ :\2/g

... 次の文字列にすべて適用された場合(連続していない場合 ...

string1\nstring2

...に変換します...

s:t:r:i:n:g:1:\nstring2
s:t:r:i:n:g:\nstring21:
s:t:r:i:n:g:1: 
 : : : : : : :\nstring2

基本的に、正規表現を使用して、適用するパターンスペースの最初の行のみを常に処理します。これにより、テストループに頼らずに、保持された最短一致と最新の両方のラインの2つの異なるバージョンをジャグリングできます。適用されたすべての置換は、パターンスペース全体を一度に処理します。

リテラル文字列/文字列比較には異なるバージョンが必要です。したがって、すべての文字が等しいことが保証されている各行のバージョンが必要です。しかし、もちろん、どちらかが実際に入力で最も早く発生する行である場合、出力に出力される行は、おそらく比較のためにサニタイズ/ホモジナイズしたものではなく、元のバージョンの行でなければなりません。したがって、それぞれ2つのバージョンが必要です。

別の必要性は、同じものを処理するために大量のバッファを切り替えることですが、少なくともどちらのバッファも現在の状態を維持するために必要な4行を超えることはありません。したがって、恐ろしいことではないでしょう。

とにかく、各サイクルで最初に発生するのは、記憶された行の変換です-実際に保存されるのはリテラルのオリジナルだけなので-に...

^               \nremembered line$

...その後、next入力行は古いバッファを上書きします。少なくとも1つの文字が含まれていない場合、事実上無視されます。それははるかに簡単ですq最初に出現する空白行でUIを実行するが、テストデータにはこれらの多くがあり、複数の段落を処理したかったのです。

そのため、文字が含まれている場合、そのリテラルバージョンは記憶されている行に追加され、その間隔比較バージョンは次のようにパターンスペースの先頭に配置されます。

^   \n               \nremembered line\nnew$

最後に、そのパターンスペースに置換が適用されます。

s/^\( *\)\(\n \1 *\)\{0,1\}\n//

そのため、少なくとも1文字の予備の記憶された行を含むために必要なスペースに改行が収まる場合、最初の2行は置き換えられ、そうでない場合は最初の行のみが置き換えられます。

結果に関係なく、パターンスペースの最初の行は、Dサイクルの終わりに常に再起動される前に削除されます。これは、新しい行が最後の文字列より短い場合...

new

...サイクルの最初の置換に返送され、常に最初の改行文字からのみ削除されます。したがって、そのまま残ります。しかし、そうでない場合は文字列...

remembered line\nnew

...代わりに次のサイクルを開始し、最初の置換はそれから文字列を取り除きます...

\nnew

...毎回。

最後の行では、記憶された行が標準出力に出力されるため、指定されたデータ例では次のように出力されます。

4for

ただし、真剣に使用してくださいtr



行番号を挿入する必要もありますか?私のOPの読み方は、最短の行だけが必要であり、必ずしもその行の行番号ではないということです。完全を期すために見せても害はないと思います。
デジタル外傷

@DigitalTrauma-いや、おそらくそうではない。しかし、それなしでは非常に有用ではありません。ストリームを処理する場合、出力で元の入力を同じように再現する手段を常に含めることを好みます。行番号により、ここでそれが可能になります。たとえば、最初のパイプラインの結果を変えるには:REINPUT | sort -t: -nk1,1 | cut -d: -f3-。2番目はsed --expression、末尾に別のスクリプトを含めるという単純な問題です。
mikeserv

@DigitalTrauma-ああ、最初の例では、入力で同じ長さの行が発生した場合、行番号sortタイブレーカーとしての動作に影響します。
mikeserv

7

試してください:

awk '{ print length, $0 }' testfile | sort -n | cut -d" " -f2- | head -1

アイデアはawk、各行の長さを最初に印刷するために使用することです。これは次のように表示されます。

echo "This is a line of text" | awk '{print length, $0}'
22 This is a line of text

その後、で行をソートする文字数を使用しsortcut回数を取り除くためにとhead、最初の行(少なくとも文字との1)を維持します。もちろん使用できますtail、この場合、ほとんどの文字を含む行を取得するためにます。

(これはこの回答から採用されました


ロジックに対して+1ですが、すべての場合に機能するわけではありません。2行の文字数が同じで、最小の場合。head -1
-Thhihi

最長の行を取得するには、使用するよりもソートを逆にする方が効率的ですtailheadジョブの完了後、入力の残りを読み取らずに終了できるため)。
トビースパイト

@Thushi正規表現を少し使用して、行番号を印刷した後、1行目と同じ番号の行以外をすべて削除して、すべての最短行を出力できます。
マシューD.ショールフィールド

5

POSIX awkの場合:

awk 'FNR==1{l=$0;next};length<length(l){l=$0};END{print l}' file

複数の行が同じ文字数であり、これも最小である場合は機能しません。
ゆえに

@Thushi:最初の最小行を報告します。
クオンルム

ええ、それは正しい出力ではありませんか?他の行にも最小文字数が含まれています。
ゆえに

1
@Thushi:OPの要件には言及されておらず、OPからの更新を待っています。
クオンルム

3
私は考えていないL変数に名前を付けることを選んだための最良の手紙だった:のようなDの何かがmin、物事をより明確になるだろう
fedorqui

3

@mikeservのアイデアの一部を借りる:

< testfile sed 'h;s/./:/g;s/.*/expr length "&"/e;G;s/\n/\t/' | \
sort -n | \
sed -n '1s/^[0-9]+*\t//p'

最初sedは次のことを行います。

  • h 元の行を保持バッファーに保存します
  • 行のすべての文字を置き換えます : -これは、コードインジェクションの危険性を取り除くためです
  • 行全体を expr length "whole line" -これは評価できるシェル式です
  • eコマンドsGNU sed拡張機能です、パターンスペースを評価し、結果をパターンスペースに戻すです。
  • G 改行とホールドスペース(元の行)の内容をパターンスペースに追加します
  • 最後sは改行をタブに置き換えます

文字数は各行の先頭の数字になったためsort -n、行の長さでソートされます。

最後のsed行は、最初の(最短の)行と行の長さを除くすべてを削除し、結果を出力します。


1
@mikeservはい、exprこちらの方がいいと思います。はい、e各行にシェルを生成します。sed式を編集して、文字列内の各文字を:evalの前のa に置き換えます。これにより、コードインジェクションの可能性がすべてなくなるはずです。
デジタル外傷

私は通常、xargs expr個人的に選択しますが、中間シェルを回避すること以外は、おそらくより文体的なことです。とにかく好きです。
mikeserv

3

一つのsed表現ですべてが可能になると思いました。それはきれいではありません:

$ sed '1h;s/.*/&\n&/;G;:l;s/\n[^\n]\([^\n]*\)\n[^\n]/\n\1\n/;tl;/\n\n/{s/\n.*//;x};${x;p};d' testfile
4for
$ 

これを分解する:

1h            # save line 1 in the hold buffer (shortest line so far)
s/.*/&\n&/    # duplicate the line with a newline in between
G             # append newline+hold buffer to current line
:l            # loop start
s/\n[^\n]\([^\n]*\)\n[^\n]/\n\1\n/
              # attempt to remove 1 char both from current line and shortest line
tl            # jump back to l if the above substitution succeeded
/\n\n/{       # matches if current line is shorter
  s/\n.*//    # remove all but original line
  x           # save new shortest line in hold buffer
}
${            # at last line
  x           # get shortest line from hold buffer
  p           # print it
}
d             # don't print any other lines

OS XのBSD sedは、改行を使用するともう少し気味が悪くなります。このバージョンは、sedのBSDバージョンとGNUバージョンの両方で機能します。

$ sed -e '1h;G;s/\([^\n]*\)\(\n\)\(.*\)/\1\2\1\2\3/;:l' -e 's/\(\n\)[^\n]\([^\n]*\n\)[^\n]/\1\2/;tl' -e '/\n\n/{s/\n.*//;x;};${x;p;};d' testfile
4for
$

これは、ベストプラクティスの回答を提供するという真剣な試みではなく、「可能性のある」回答であることに注意してください。コードコルフのプレイが多すぎることを意味すると思います


man sedOS Xの@mikeserv From :「エスケープシーケンス\ nは、パターンスペースに埋め込まれた改行文字と一致します」。だから、GNU sed \nは正規表現と置換で許可さ\nれているのに対して、BSD は正規表現でのみ許可されており、置換では許可されていないと思います。
デジタル外傷

\nパターンスペースから借用するのは良い考えであり、2番目のs///式で機能しますが、s/.*/&\n&/式は\n以前にはなかったパターンスペースにa を挿入しています。また、BSD sedは、ラベルの定義と分岐の後にリテラルの改行を必要とするようです。
デジタル外傷

1
これらの改行はパラメーター区切り記号です-任意のパラメーターを受け入れる可能性のあるコマンドを区切るために必要です-少なくとも、それは仕様が言っていることです。仕様では、sedスクリプトは改行で終わる必要がないことを除いて、テキストファイルでなければならないことも示されています。そのため、通常は個別の引数としても区切ることができます- sed -e :\ label -e :\ label2など。1hとにかくやっているのでx;H、改行に基づいて何らかのロジックに切り替えることができます。また、サイクルの終わりにパターンスペースから先頭の改行をトリムできますD
mikeserv

@mikeservニース。はい、G最初の操作を行い、s///式を変更して、必要な改行を挿入しました。を-e使用して分割すると、文字どおりの改行なしで、すべてを1つの(長い)行に移動できます。
デジタル外傷

\nエスケープはのためにspec'dされsedすぎ、のLHS、と私はそれがPOSIXブラケット表現はまた、すべての文字がその特別な意味を失うようにspec'dされていることを除いて、逐語的にスペックの発言だと思う- (明示的に含むと\\ -括弧、範囲区切り記号としてのダッシュ、およびドット、イコール、キャレット、照合用コロン、等価、否定、およびクラスを除く1つ内。
mikeserv

2

別のperlソリューション:行を配列のハッシュに格納します。ハッシュキーは行の長さです。次に、最小限のキーで行を印刷します。

perl -MList::Util=min -ne '
    push @{$lines{ length() }}, $_;
} END {
    print @{$lines{ min keys %lines }};
' sample 
4for

を使用push @{$lines{+length}};してprint @{$lines{+min keys %lines}};、入力を少なくすることができます:)
cuonglm

私がゴルフだった場合、私はどちらかの変数名「行」を使用していません:perl -MList::Util=min -nE'push @{$l{+length}},$_}END{say@{$l{min keys%l}}' sample
グレン・ジャックマン

非golfedバージョン(作品!)のための1、のみ印刷用かかわらず、すべてのバリアント。– perlpar.with perlの不可解な性質に達していない私たちにとっては少し気味が悪い。ところで。ゴルフさsayれた人は、出力の最後に偽の空白行を印刷します。
Peter.O

2

最初の最短行だけを取得するには:

f=file; sed -n "/^$(sed 's/./1/g' $f | sort -ns | sed 's/././g;q')$/{p;q}" $f

すべての最短リントを取得するには、次のように変更{p;q}しますp


別の方法(やや珍しい)は、長さでsort実際のソートを行うことです。短いラインでも比較的遅く、ラインの長さが長くなると劇的に遅くなります。
しかし、キーオーバーラップせてソートするというアイデアは非常に興味深い思います。他の人もそれを興味深く/有益と感じるかもしれない場合に備えて、私はそれを投稿しています。

仕組み:
同じキーの長さのバリエーションで並べ替え- key 1行全体にまたがり
ます。連続するキーバリエーションごとに、ファイルの最長行の長さ(で決定されるwc -L)までキーの長さが1文字ずつ増加します

最初の(ソートされた)最短行のみを取得するには:

f=file; sort -t'\0' $(seq -f "-k1.%0.0f" $(<"$f" wc -L) -1 1) "$f" | head -n1

次と同じです:

f=file.in; 
l=$(<"$f" wc -L)
k=$(seq -f "-k1.%0.0f" $l -1 1) 
sort -st'\0' $k "$f" | head -n1

2

空白行は最短行とは見なされず、空白行が存在する可能性があると仮定すると、次の純粋なAWKが機能します。

awk '
    {
        len   = length;
        a[$0] = len
    }
    !len { next }
    !min { min = len }
    len < min { min = len }
    END {
        for (i in a)
            if (min == a[i])
                print i
    }
' infile.txt

2

sortの使用はどうですか?

awk '{ print length($0) "\t" $0 }' input.txt | sort -n | head -n 1 | cut -f2-

1

GNU awkを使用

gawk '
    {
         a[length]=$0
    };
    END
    {
        PROCINFO["sorted_in"]="@ind_num_asc";
        for (i in a)
        {
            print a[i]; 
            exit
        }
    }
    ' file
  • 行の長さでインデックス付けされた配列に各行を読み込みます。

  • に設定PROCINFO["sorted_in"]する@ind_num_ascと、配列スキャンが配列インデックスによって順序付けされ、数値でソートされます。

  • PROCINFO上記のように設定すると、配列のトラバースで最初に最小長のラインがピックアップされます。したがって、配列の最初の要素を出力して終了します

これには、nlogn他のアプローチのいくつかがn間に合っているという欠点があります


1

ミッドレベルなしでシェルツールの方法、sedまたはawk

f=inputfile
head -n $(xargs -d '\n' -L 1 -I % sh -c 'exec echo "%" | wc -c' < $f | 
          cat -n | sort -n -k 2 | head -1 | cut -f 1)  $f | tail -1

$f変数が必要ないのはいいことです。tee何とかして使用できる可能性があるという考えを持っています...
agc
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.