95

私はテキストファイルを持っています:

1 Q0 1657 1 19.6117 Exp
1 Q0 1410 2 18.8302 Exp
2 Q0 3078 1 18.6695 Exp
2 Q0 2434 2 14.0508 Exp
2 Q0 3129 3 13.5495 Exp

次のように、すべての行の 2 番目と 4 番目の単語を取得します。

1657 19.6117
1410 18.8302
3078 18.6695
2434 14.0508
3129 13.5495

私はこのコードを使用しています:

 nol=$(cat "/path/of/my/text" | wc -l)
 x=1
 while  [ $x -le "$nol" ]
 do
     line=($(sed -n "$x"p /path/of/my/text)
     echo ""${line[1]}" "${line[3]}""  >> out.txt
     x=$(( $x + 1 ))
 done

動作しますが、非常に複雑で、長いテキスト ファイルを処理するには長い時間がかかります。

これを行う簡単な方法はありますか?

4

6 に答える 6

143

ちゃんと覚えたら :

cat filename.txt | awk '{ print $2 $4 }'

または、コメントで述べたように:

awk '{ print $2 $4 }' filename.txt
于 2013-06-16T20:17:20.190 に答える
72

cut次のコマンドを使用できます。

cut -d' ' -f3,5 < datafile.txt

版画

1657 19.6117
1410 18.8302
3078 18.6695
2434 14.0508
3129 13.5495

  • -d' '-意味、space区切り文字として使用
  • -f3,5- 3 列目と 5 列目を取り出して印刷する

純粋なシェル ソリューションとして、大きなファイルの場合cutはるかに高速です。ファイルが複数の空白で区切られている場合は、次のように最初にそれらを削除できます。

sed 's/[\t ][\t ]*/ /g' < datafile.txt | cut -d' ' -f3,5

(gnu) sed は、tabまたはspace文字を単一のに置き換えますspace

バリアントの場合-ここにもperlソリューションがあります:

perl -lanE 'say "$F[2] $F[4]"' < datafile.txt
于 2013-06-16T20:26:41.467 に答える
27

完全を期すために:

while read -r _ _ one _ two _; do
    echo "$one $two"
done < file.txt

代わりに_任意の変数 ( などjunk) を使用することもできます。ポイントは、列を抽出することです。

デモ:

$ while read -r _ _ one _ two _; do echo "$one $two"; done < /tmp/file.txt
1657 19.6117
1410 18.8302
3078 18.6695
2434 14.0508
3129 13.5495
于 2013-06-16T22:09:16.497 に答える
9

もう 1 つの単純なバリアント -

$ while read line
  do
      set $line          # assigns words in line to positional parameters
      echo "$3 $5"
  done < file
于 2013-08-20T14:48:24.650 に答える
4

ファイルにn行が含まれている場合、スクリプトはファイルをn回読み取る必要があります。したがって、ファイルの長さを 2 倍にすると、スクリプトが実行する作業の量は 4 倍になります。そして、行を順番にループするだけなので、その作業のほとんどすべてが単純に破棄されます。

代わりに、ファイルの行をループする最良の方法は、組み込みwhileの条件コマンドでループを使用することです。read

while IFS= read -r line ; do
    # $line is a single line of the file, as a single string
    : ... commands that use $line ...
done < input_file.txt

あなたの場合、行を配列に分割したいので、readビルトインは実際に配列変数を設定するための特別なサポートを持っています。これはあなたが望むものです:

while read -r -a line ; do
    echo ""${line[1]}" "${line[3]}"" >> out.txt
done < /path/of/my/text

またはさらに良い:

while read -r -a line ; do
    echo "${line[1]} ${line[3]}"
done < /path/of/my/text > out.txt

ただし、実行していることについては、cutユーティリティを使用できます。

cut -d' ' -f2,4 < /path/of/my/text > out.txt

(またはawk、Tom van der Woerdt が示唆するように、またはperl、またはsed)。

于 2013-06-16T20:27:01.757 に答える