在文本文件中取第n列

mnr*_*nrl 76 linux bash

我有一个文本文件:

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
Run Code Online (Sandbox Code Playgroud)

我想把每一行的第2和第4个单词都这样:

1657 19.6117
1410 18.8302
3078 18.6695
2434 14.0508
3129 13.5495
Run Code Online (Sandbox Code Playgroud)

我正在使用此代码:

 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
Run Code Online (Sandbox Code Playgroud)

它有效,但它非常复杂,需要很长时间才能处理长文本文件.

有更简单的方法吗?

Tom*_*rdt 112

iirc:

cat filename.txt | awk '{ print $2 $4 }'
Run Code Online (Sandbox Code Playgroud)

或者,如评论中所述:

awk '{ print $2 $4 }' filename.txt
Run Code Online (Sandbox Code Playgroud)

  • UUOC!`awk'{print $ 2,$ 4}'filename.txt`更好(没有管道,只有一个程序被调用) (14认同)
  • @TomvanderWoerdt:为了这个目的,我有时会写`<input awk'{print $ 2 $ 4}'> output`. (7认同)
  • @blue我经常在我的bash脚本中使用`cat`而不是指定文件名,因为开销很小,因为语法`cat ... | ...> ...`非常清楚地显示输入是什么以及输出的位置.你是对的,这里实际上并不需要它. (4认同)

jm6*_*666 63

您可以使用以下cut命令:

cut -d' ' -f3,5 < datafile.txt
Run Code Online (Sandbox Code Playgroud)

版画

1657 19.6117
1410 18.8302
3078 18.6695
2434 14.0508
3129 13.5495
Run Code Online (Sandbox Code Playgroud)

  • -d' '- 意思是,space用作分隔符
  • -f3,5 - 拍摄并打印第3和第5列

cut要快得多对于大文件作为一个纯粹的外壳解决方案.如果您的文件使用多个空格分隔,则可以先删除它们,例如:

sed 's/[\t ][\t ]*/ /g' < datafile.txt | cut -d' ' -f3,5
Run Code Online (Sandbox Code Playgroud)

其中(gnu)sed将用单个替换任何tabspace字符space.

对于变体 - 这里也是一个perl解决方案:

perl -lanE 'say "$F[2] $F[4]"' < datafile.txt
Run Code Online (Sandbox Code Playgroud)

  • 效果很好...如果你保证每行的空格数准确...:) (2认同)

Joh*_*iss 24

为了完整起见:

while read _ _ one _ two _; do
    echo "$one $two"
done < file.txt
Run Code Online (Sandbox Code Playgroud)

也可以使用而不是_任意变量(例如junk).关键是要提取列.

演示:

$ while read _ _ 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
Run Code Online (Sandbox Code Playgroud)


小智 6

一个更简单的变种 -

$ while read line
  do
      set $line          # assigns words in line to positional parameters
      echo "$3 $5"
  done < file
Run Code Online (Sandbox Code Playgroud)