在Linux中使用制表符替换空格


Answers:


168

使用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'').

4
哇,从来不知道存在扩展/未扩展。我试图做相反的事情,并且扩展是完美的,而不是不得不与tror 混为一谈sed
易卜拉欣

4
为了便于记录,请展开/展开为标准实用程序
2013年

4
太酷了,这些都是标准的。我喜欢UNIX哲学。如果可以的话会很好。
马修·弗拉申

3
我不认为unexpand将在这里工作..它仅转换前导空格,只用两个或多个空格..在这里看到:lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
olala 2013年

13
请注意-展开不会将单个空格转换为制表符。如果需要将所有0x20字符的运行盲目转换为单个选项卡,则需要其他工具。
史蒂夫·S.

44

我认为您可以尝试使用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

4
在您的sed示例中,最佳实践表明,出于效率/速度方面的考虑,您使用tr替换sed上的单个字符。同样,通过这种方式可以很容易地找到tr例子:tr ' ' \\t < someFile > someFile
Sam Bisbee

2
当然,tr具有比sed更好的性能,但是我喜欢Unix的主要原因是有很多方法可以做某事。如果您打算多次执行此替换,则将搜索性能良好的解决方案,但是如果仅执行一次,则将寻求一个包含使您感到舒适的命令的解决方案。
乔纳森(Jonathan)2009年

2
arg。我不得不反复试验才能使sed正常工作。我不知道为什么我必须这样逃避加号:ls -l | sed "s/ \+/ /g"
Jess

随着awk -v OFS="\t" '$1=$1' file1我注意到,如果你有一个行开始用数字0(例如0 1 2),则该行会从结果ommitted。
Nikola Novak 2014年

@Jess您发现“正确的默认语法”正则表达式。缺省情况下,sed将单(未转义)加号视为简单字符。其他某些字符(例如'?',...)也是如此,您可以在此处找到更多信息:gnu.org/software/sed/manual/html_node/…。可以在此处找到类似的语法详细信息(请注意,这是grep的人,而不是sed):gnu.org/software/grep/manual/grep.html#Basic-vs-Extended
Victor Yarema '16

11

使用Perl

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

3
用单个选项卡替换连续的空格时也遇到类似的问题。Perl仅在正则表达式上添加了“ +”来工作。
2013年

不过,我当然想做相反的事情:将制表符转换为两个空格:perl -p -i -e 's/\t/ /g' *.java
TimP

我可以递归执行吗?
亚伦·弗兰克

9

更好的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
奥马尔的

3

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

从包含纯文本文件的文件夹内部放置并执行脚本。

#!/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;

2

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

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

在Cygwin的测试在Windows 7中
arkod

1

您也可以使用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.`

0

如果您要谈论用制表符替换一行中的所有连续空格,请使用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其他答案中所述。


0

使用sed

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

要么

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

-1

这将用一个空格(而不是制表符)替换连续的空格。

tr -s '[:blank:]'

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

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

实际上,-c它使用替换不是空格的连续字符。
wingedsubmariner

1
问题是关于标签,这不是答案。
马修(Matthew)阅读
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.