使用剪切重新排列列

Boo*_*ean 122 shell

我有以下格式的文件

Column1    Column2
str1       1
str2       2
str3       3

我希望重新排列列.我试过下面的命令

cut -f2,1 file.txt

该命令不会对列重新排序.知道为什么它不工作?

谢谢.

Ign*_*ams 139

对于cut(1)手册页:

使用-b,-c或-f中的一个,只有一个.每个LIST由一个范围组成,或由逗号分隔的多个范围组成.选定的输入按照与读取相同的顺序写入,并且只写入一次.

它首先到达字段1,然后打印,然后是字段2.

awk改为使用:

awk '{ print $2 " " $1}' file.txt
Run Code Online (Sandbox Code Playgroud)

  • 太糟糕了`cut`不支持这种直观的重新排序命令.无论如何,另一个提示:您可以使用`awk`的`-FS`和`-OFS`选项来使用自定义输入和输出字段分隔符(例如`-d`和`--output-delimiter`用于`cut`) . (12认同)
  • 对不起,`FS`是一个选项,`OFS`是一个变量.例如`awk -v OFS =";" -F"\ t"'{print $ 2,$ 1}'` (12认同)
  • 对于Git Bash的Windows用户的注意事项:如果您从上面的命令中得到奇怪的输出,看起来像列相互覆盖,那么回车就是罪魁祸首.将文件中的EOL从CRLF更改为LF. (2认同)
  • 这个非常简单但可能对某些人有用,只需用\ t替换空格以便通过制表符进行重新排序,如果你想要更多的列,你可以这样做,例如`awk'{print $ 4"\ t"$ 2"\t"$ 6"\ t"$ 7}'档案' (2认同)

Jus*_*ser 59

你也可以同时cutpaste:

paste <(cut -f2 file.txt) <(cut -f1 file.txt)
Run Code Online (Sandbox Code Playgroud)

通过评论:可以避免bashisms并删除一个切割实例:

paste file.txt file.txt | cut -f2,3
Run Code Online (Sandbox Code Playgroud)

  • 不确定这是否合格"巧妙",但是:f = file.txt paste <(cut -f2 $ f)<(cut -f1 $ f).另外,我注意到当你有很多列并希望移动它们的大块时,这种方法是最简单的. (3认同)
  • @kraymer你是什么意思?只要你有一个独特的列分隔符,`cut`适用于可变长度的列. (2认同)
  • 可以通过以下方式避免 *`bash`isms* 并删除一个 `cut` 实例:`paste file.txt file.txt | 剪切 -f2,3` (2认同)

gho*_*g74 7

只使用shell,

while read -r col1 col2
do
  echo $col2 $col1
done <"file"
Run Code Online (Sandbox Code Playgroud)


Met*_*Met 7

您可以使用Perl:

perl -ane 'print "$F[1] $F[0]\n"' < file.txt
Run Code Online (Sandbox Code Playgroud)
  • -e选项意味着在它之后执行命令
  • -n表示逐行读取(打开文件,在本例中为STDOUT,并在行上循环)
  • -a表示将这些行拆分为名为@F的向量("F" - 类似Field).Perl索引从0开始的向量不同于cut,它指示从1开始的字段.
  • 您可以在读取文件而不是默认空格时添加-F 模式(在-F和模式之间没有空格)以将模式用作字段分隔符

运行perl的优点是(如果你知道Perl)你可以在F上进行比重新排列更多的计算.


agc*_*agc 6

使用join

join -t $'\t' -o 1.2,1.1 file.txt file.txt
Run Code Online (Sandbox Code Playgroud)

笔记:

  • -t $'\t'GNU join更直观-t '\t' 没有$失败,(coreutils的 v8.28和更早?); 这可能是一个错误,$应该需要一种解决方法。请参阅:unix join separator char

  • join需要两个文件名,即使只有一个文件正在处理。两次使用相同的名称可以join执行所需的操作。

  • 对于资源join较少的系统,其占用空间比其他答案中使用的一些工具要小:

    wc -c $(realpath `which cut join sed awk perl`) | head -n -1
      43224 /usr/bin/cut
      47320 /usr/bin/join
     109840 /bin/sed
     658072 /usr/bin/gawk
    2093624 /usr/bin/perl
    
    Run Code Online (Sandbox Code Playgroud)