重新排列文本文件中的列范围

时间:2016-04-11 18:56:51

标签: ruby perl awk sed cut

我希望重新排列文本文件中的某些列。

基本上我有32列,想要1-4,6-29,5,32

我可以用awk强行说出来,但这看起来很愚蠢。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以对awkcut进行组合,假设字段由空格分隔:

awk '{$30=$5;$31=$32}1' file | cut -d' ' -f5,32 --complement

例如:

$ seq 32 | paste -s | 
  awk '{$30=$5;$31=$32}1' | 
  cut -d' ' -f5,32 --complement

1 2 3 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 5 32

答案 1 :(得分:1)

我假设您的意思是文件的每一行包含32个字符,后跟换行符,并且您希望提取由以下各项给出的相邻列组的字符串:

column_groups = [1..4, 6..29, 5, 32]

假设您已将输入文件读入数组并

line = "abcdefghijklmnopqrstuvwxyzABCDEF\n"
  #     0        10        20        30 (offsets)

是该数组的一个元素。

然后你可以这样做:

range_offsets = column_groups.map do |obj|
  case obj
  when Range
    obj.first-1..obj.last-1
  else
    obj-1..obj-1
  end
end
  #=> [0..3, 5..28, 4..4, 31..31]

arr = line.chars
  #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
  #    "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  #    "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "\n"] 

range_offsets.map { |range| arr.values_at(*[*range]).join }
  #=> ["abcd", "fghijklmnopqrstuvwxyzABC", "e", "F"]

如果您希望返回单个字符串,请将另一个join添加到结尾:

range_offsets.map { |range| arr.values_at(*[*range]).join }.join
  #=> "abcdfghijklmnopqrstuvwxyzABCeF"