如何使用perl -lane命令行选择特定的列?

时间:2018-12-27 19:02:14

标签: shell perl

下面的命令行对我有用

perl -F'\t' -lane'print join ",", @F[1,2]' inputfile

但是我想传递一个可变的列列表,而不必传递@F[1,2]中指定的列1和2。

例如,基于输入文件的总列数,我想选择一个随机子集"$random-columns"并将其传递给@F[$random-columns]

我该怎么做?

我尝试首先生成一个1到50之间的5个随机列号的columnList:

columnList=()
for (( i = 0; i <= 5-1; ++i ))
do
    (( randCol = ($RANDOM % 50) + 1 ))
    columnList[i]=$randCol
done

然后我执行以下操作以插入逗号:

cols_new=$(IFS=,; echo "${columnList[*]}")

并尝试按如下所示将其传递给perl命令行(无效):

perl -F'\t' -lane'print join ",", @F[$cols_new]' inputfile

4 个答案:

答案 0 :(得分:1)

使用rand

0至50之间的五个随机数:

@randoms = map {int(rand(50))} 1..5;

单线:

perl -F'\t' -lane 'print join ",", @F[map {int(rand(50))} 1..5]' inputfile

要对每行使用相同的随机列索引,请使用BEGIN块,该块仅在程序开始时执行一次:

perl -F'\t' -lane 'BEGIN {@rand = map {int(rand(50))} 1..5]}; print join ",", @F[@rand]' inputfile

答案 1 :(得分:1)

您的perl -e'...$cols_new...'使用的是单壳引号,因此壳不会插入变量。

虽然您可以使用插值法或命令行参数将信息从外壳程序获取到perl oneliner,但通常环境变量的麻烦程度较小:

export cols_new=1,2
perl -F'\t' -lane 'print join ",", @F[split /,/, $ENV{cols_new}]' inputfile

答案 2 :(得分:1)

您可以在Perl中进行随机数生成:

perl -F'\t' -lane 'BEGIN { @cols = map int(rand 50) + 1, 1 .. 5 } print join ",", @F[@cols]' inputfile

答案 3 :(得分:0)

非常感谢大家! 我按照您的建议解决了问题(见下文):

  • 从2- $ fileColumnCount范围内随机选择$ extractColumnCount列, 对其进行排序,并将其放入$ cols_new_temp

cols_new_temp = $(echo $(shuf -i 2- $ fileColumnCount -n $ extractColumnCount | sort -n))

回显$ cols_new_temp

  • 在这里我添加逗号来分隔列标签数组并将其放置在$ cols_new

cols_new = $(回显$ cols_new_temp | sed's / /,/ g')

echo $ cols_new

  • 此Perl oneliner从$ file1中指定的文件中检索预先指定的随机选择列($ cols_new)的子集,并添加第一列和输出列。然后将生成的文件另存为$ file2

output_col = 1

time perl -F','-lane“ print join q(,),@F [split”,“ $ output_col,$ cols_new]” $ file1> $ file2