【问题标题】:Replace whitespaces with tabs in linux在linux中用制表符替换空格
【发布时间】:2009-09-14 21:57:13
【问题描述】:

如何在给定的文本文件中用 linux 中的制表符替换空格?

【问题讨论】:

    标签: linux tabs whitespace


    【解决方案1】:

    使用 unexpand(1) 程序


    UNEXPAND(1)                      User Commands                     UNEXPAND(1)
    
    NAME
           unexpand - convert spaces to tabs
    
    SYNOPSIS
           unexpand [OPTION]... [FILE]...
    
    DESCRIPTION
           Convert  blanks in each FILE to tabs, writing to standard output.  With
           no FILE, or when FILE is -, read standard input.
    
           Mandatory arguments to long options are  mandatory  for  short  options
           too.
    
           -a, --all
                  convert all blanks, instead of just initial blanks
    
           --first-only
                  convert only leading sequences of blanks (overrides -a)
    
           -t, --tabs=N
                  have tabs N characters apart instead of 8 (enables -a)
    
           -t, --tabs=LIST
                  use comma separated LIST of tab positions (enables -a)
    
           --help display this help and exit
    
           --version
                  output version information and exit
    . . .
    STANDARDS
           The expand and unexpand utilities conform to IEEE Std 1003.1-2001
           (``POSIX.1'').
    

    【讨论】:

    • 哇,从来不知道展开/取消展开存在。我试图做相反的事情,并且扩展是完美的,而不必乱用trsed
    • 备案,展开/取消展开为standard utilities
    • 太酷了,这些都是标准的。我喜欢UNIX philosophy。如果它可以就地完成就好了。
    • 我不认为 unexpand 可以在这里工作。它只转换前导空格,并且只有两个或多个空格。见这里:lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
    • 请注意 - unexpand 不会将单个空格转换为制表符。如果您需要盲目地将所有运行的 0x20 字符转换为单个选项卡,则需要不同的工具。
    【解决方案2】:

    我觉得你可以试试 awk

    awk -v OFS="\t" '$1=$1' file1
    

    如果您愿意,也可以选择 SED

    sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt
    

    甚至是tr

    tr -s '\t' < thefile.txt | tr '\t' ' ' > the_modified_copy.txt
    

    或 Sam Bisbee 建议的 tr 解决方案的简化版本

    tr ' ' \\t < someFile > someFile
    

    【讨论】:

    • 在您的 sed 示例中,出于效率/速度的原因,最佳实践要求您使用 tr 替换 sed 上的单个字符。此外,这样的例子更容易:tr ' ' \\t &lt; someFile &gt; someFile
    • 当然,tr 的性能比 sed 好,但我喜欢 Unix 的主要原因是有很多方法可以做某事。如果您计划多次执行此替换,您将搜索性能良好的解决方案,但如果您只打算执行一次,您将搜索包含让您感觉舒适的命令的解决方案。
    • 参数。我不得不使用反复试验来使 sed 工作。我不知道为什么我必须像这样逃避加号:ls -l | sed "s/ \+/ /g"
    • awk -v OFS="\t" '$1=$1' file1 我注意到如果你有一行以数字0开头(例如0 1 2),那么该行将从结果中省略。
    • @Jess 您找到了“正确的默认语法”正则表达式。默认情况下 sed 将单个(未转义)加号视为简单字符。其他一些字符也是如此,例如 '?', ...您可以在此处找到更多信息:gnu.org/software/sed/manual/html_node/…。类似的语法细节可以在这里找到(注意这是 grep 的 man,而不是 sed):gnu.org/software/grep/manual/grep.html#Basic-vs-Extended.
    【解决方案3】:

    使用 Perl

    perl -p -i -e 's/ /\t/g' file.txt
    

    【讨论】:

    • 在用单个制表符替换连续空格时遇到了类似的问题。 Perl 只在正则表达式中添加了一个“+”。
    • 当然,我想做相反的事情:将制表符转换为两个空格:perl -p -i -e 's/\t/ /g' *.java
    • 我可以递归执行此操作吗?
    • 这是唯一对我有用的变体;我使用s/ {4}/ 将 4 空格缩进转换为制表符。
    【解决方案4】:

    更好的tr命令:

    tr [:blank:] \\t
    

    这将清理 unzip -l 的输出,以便使用 grep、cut 等进行进一步处理。

    例如,

    unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
    

    【讨论】:

    • 我不必使用引号来让它工作:tr [:blank:] \\t
    【解决方案5】:

    将当前目录下的每个.js文件转换为制表符的示例命令(仅转换前导空格):

    find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
    

    【讨论】:

    • 在 Windows 7 上的 cygwin 中测试。
    【解决方案6】:

    下载并运行以下脚本,以递归方式将纯文本文件中的软标签转换为硬标签。

    在包含纯文本文件的文件夹中放置并执行脚本。

    #!/bin/bash
    
    find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
        echo "Converting... "$file"";
        data=$(unexpand --first-only -t 4 "$file");
        rm "$file";
        echo "$data" > "$file";
    }; done;
    

    【讨论】:

      【解决方案7】:

      您也可以使用astyle。我发现它非常有用,它也有几个选项:

      Tab and Bracket Options:
         If  no  indentation  option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4.  If no brackets option is set, the
         brackets will not be changed.
      
         --indent=spaces, --indent=spaces=#, -s, -s#
                Indent using # spaces per indent. Between 1 to 20.  Not specifying # will result in a default of 4 spaces per indent.
      
         --indent=tab, --indent=tab=#, -t, -t#
                Indent using tab characters, assuming that each tab is # spaces long.  Between 1 and 20. Not specifying # will result in a default assumption  of
                4 spaces per tab.`
      

      【讨论】:

        【解决方案8】:

        使用 sed

        T=$(printf "\t")
        sed "s/[[:blank:]]\+/$T/g"
        

        sed "s/[[:space:]]\+/$T/g"
        

        【讨论】:

          【解决方案9】:

          如果您说的是用制表符替换一行中的所有连续空格,那么tr -s '[:blank:]' '\t'

          [root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda
          Device         Start
          /dev/sda1       2048
          /dev/sda2     411648
          /dev/sda3    2508800
          /dev/sda4   10639360
          /dev/sda5   75307008
          /dev/sda6   96278528
          /dev/sda7  115809778
          [root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t'
          Device  Start
          /dev/sda1       2048
          /dev/sda2       411648
          /dev/sda3       2508800
          /dev/sda4       10639360
          /dev/sda5       75307008
          /dev/sda6       96278528
          /dev/sda7       115809778
          

          如果您要替换所有空格(例如空格、制表符、换行符等),那么tr -s '[:space:]'

          [root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t'
          Device  Start   /dev/sda1       2048    /dev/sda2       411648  /dev/sda3       2508800 /dev/sda4       10639360        /dev/sda5       75307008        /dev/sda6     96278528        /dev/sda7       115809778  
          

          如果您要修复标签损坏的文件,请使用 expandunexpand,如其​​他答案中所述。

          【讨论】:

            【解决方案10】:

            这会将连续的空格替换为一个空格(但不是制表符)。

            tr -s '[:blank:]'
            

            这将用制表符替换连续的空格。

            tr -s '[:blank:]' '\t'
            

            【讨论】:

            • 实际上,-c 会替换为 空格的连续字符。
            • 问题是关于标签的,这不是答案。
            【解决方案11】:
            sed 's/[[:blank:]]\+/\t/g' original.out > fixed_file.out
            

            这将例如减少制表符的数量..或空格到一个制表符中。

            你也可以针对多个空格/制表符合并为一个空格的情况:

            sed 's/[[:blank:]]\+/ /g' original.out > fixed_file.out
            

            【讨论】:

              猜你喜欢
              • 2020-03-11
              • 2010-09-30
              • 1970-01-01
              • 2011-10-06
              • 2017-06-10
              • 2011-10-05
              • 1970-01-01
              • 2023-04-05
              • 2011-08-25
              相关资源
              最近更新 更多