使用Gedit或命令行是否可以修改文本文件的每四行?


11

我正在尝试将文本文件转换为制表符分隔的电子表格。我的文本文件是这样的:

Dog
Cat
Fish
Lizard
Wolf
Lion
Shark
Gecko
Coyote
Puma
Eel
Iguana

借助Gedit或LibreOffice中的标准搜索和替换功能,可以轻松地用标签替换行尾。但是,如果我只是将回车换成制表符,我将得到:

Dog   Cat   Fish   Lizard   Wolf   Lion   Shark   Gecko   Coyote   Puma   Eel   Iguana

但是我需要做的就是让它看起来像这样:

Dog   Cat   Fish   Lizard
Wolf   Lion   Shark   Gecko  
Coyote   Puma   Eel   Iguana

因此,每四行,是否可以将每个行尾字符换成一个制表符?

我不知道是否可以使用Gedit或LibreOffice之类的程序中的正则表达式来完成这种条件迭代,所以也许这需要某种命令行功能吗?我什至不清楚最好的工具是什么。


更新:

我尝试了以下命令:

sed 'N;N;N;s/\n/\t/g' file > file.tsv

paste - - - - < file > file.tsv

pr -aT -s$'\t' -4 file > file.tsv

xargs -d '\n' -n4 < inputfile.txt

但是,当我尝试tsv在LibreOffice中打开生成的文件时,这些列不太正确。我不确定这是否表示我没有正确执行上述命令,还是在LibreOffice导入功能中做错了什么:

TSV在Calc中打开

仅供参考,所需结果应如下所示:

适当的栏

Answers:


16

可以使用命令行编辑器,例如sed

sed 'N;N;N;s/\n/\t/g' file > file.tsv

或者,更编程地,通过使用GNU sed的地址运算符将反斜杠的行连续字符添加到要连接的每行中n skip m,并使用经典的单线跟随它来连接连续的行:

sed '0~4! s/$/\t\\/' file | sed -e :a -e '/\\$/N; s/\\\n//; ta'

例如,参见Sed单行解释

  1. 如果它以反斜杠“ \”结尾,则将其追加到下一行。

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

但是,使用其他标准文本处理实用程序之一,恕我直言itwo应该会更容易

paste - - - - < file > file.tsv

-将对应于列数)或

pr -aT -s$'\t' -4 file > file.tsv

-s$'\t如果您不介意输出由多个选项卡分隔,则可以省略)。


您观察到的奇怪的重新导入行为几乎可以肯定是因为原始文件具有Windows样式的CRLF行尾。如果需要使用Windows中的文件,则可以通过多种方式将转换转换为命令

tr -d '\r' < file.csv | paste - - - -

要么

sed 'N;N;N;s/\r\n/\t/g' file.csv

前者将删除所有回车,而后者将在每个新行的末尾保留一个CR(如果目标最终用户在Windows上,则可能是您想要的)。


1
关于Windows样式的行尾的注释:和在Unix样式之间进行转换的标准工具是dos2unixand unix2dos
大卫·佛斯特

13

您可以使用xargs始终将四行组合为一组,每行之间用一个空格隔开:

xargs -d '\n' -n4 < inputfile.txt

-d '\n'将输入定界符设置为换行符,否则也会在空格处中断。如果每条输入线只有一个字,您甚至可以忽略它。
-n4将参数编号(每条输出行的输入项数)设置为4。

输出:

Dog Cat Fish Lizard
Wolf Lion Shark Gecko
Coyote Puma Eel Iguana

或者,如果您希望将制表符用作分隔符而不是空格,则可以在以后替换它们。但是,如果输入行中有空格,则这些空格也会被替换:

xargs -d '\n' -n4 | tr ' ' '\t'

输出(外观取决于浏览器/终端的标签宽度):

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana

此方法的优点是,即使输入的总行数不是四的倍数,它也可以合理地运行。
伊利亚·卡根

3

您还可以使用:

awk -v ORS="" '{print $1; print NR%4==0?"\n":"\t"}' file > file.tsv 

两个awk内置变量是:

  • ORSø安输出ř的eCord 小号 eparator(缺省值=新行)。它被添加到每个打印命令的末尾。
  • NRÑ当前的棕土ř流awk处理。

对于每行,此命令将显示第一列(仅此处)的内容。然后,通过测试NR除以4 的余数,选择添加换行符或制表符。


3

另一个最短的awk方法:

awk '{printf $0 (NR%4?"\t":"\n")}' infile

printf的唯一一列,然后下一旁边还有...还有一个选项卡\t每个字符后,反而会printf的一个\newline字符时ň的赭[R的eCord是因子4(其中NR%4将返回0(假),而这正是三元运算符condition(s)?when-true:when-false是在做。)


3

我对此的解决方案是使用sed和的组合sed。首先,您可以>使用以下解决方案在第四行中标记一些特殊字符:

在这种情况下,您要从第5行开始并在其后的每第4行进行标记。在GNU sed中可以作为地址给出5~4。您可以使用以下命令:

sed '5~4s/^/>/' file1 > file2

然后,您需要删除换行符,可以sed循环执行此操作:

sed ':a;N;s/\n/ /;ba' file2 > file3

有更简单的方法可以将换行符转换为其他字符,例如tr

tr '\n' ' ' < file2 > file3

无论哪种方式,将两者结合起来

Dog   Cat   Fish   Lizard   >Wolf   Lion   Shark   Gecko   >Coyote   Puma   Eel   Iguana

(该sed版本留下了换行符,而该tr版本则没有)

之后,您只需要将插入的特殊字符转换为换行符即可;例如,参见转换制表符分隔的文件以使用换行符。在这种情况下,请更改>为换行符:

sed 'y/>/\n/' file3 > outfile

y命令执行与tr将一个字符转换为另一个字符相同的功能,但是您可以在s此处很好地使用该命令。使用s,您需要g对(sed 's/>/\n/g')行中的每个匹配项进行操作。

您可以使用管道来代替制作两个中间文件:

$ sed '5~4s/^/>/' file | sed ':a;N;s/\n/ /;ba' | sed 'y/>/\n/'
Dog Cat Fish Lizard 
Wolf Lion Shark Gecko 
Coyote Puma Eel Iguana

如果尾随空格有问题,则可以添加另一个命令来删除它们:

| sed 's/ $//'

2

为了“完整性”,这里有一个纯bash解决方案:

#!/usr/bin/env bash

sep=$'\t'

while read one \
      && read two \
      && read three \
      && read four
do
  printf "%s\n" "$one$sep$two$sep$three$sep$four"
done

假设IFS正确设置(默认情况下应为AFAIK),也可以与空格一起使用。而且,我认为这甚至可以是可移植的shell脚本,并且可以与任何POSIX兼容的shell一起使用。


1
通常,这不能移植到POSIX兼容的shell,因为$' 'POSIX不需要引用形式。例如,在dashsh默认情况下在Ubuntu上提供)的in中,printf '%s\n' $'a\tb'仅运行output $a\tb。但这并不意味着它没有用。它确实可以正常工作。但是,与其他人发布的其他解决方案一样,如果输入的行数不是四的倍数,它将产生不完整的输出。另外,我建议使用read -r,因为这里没有理由认为不需要在输入文件中扩展反斜杠转义。
伊莱亚·卡根

您可以做printf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$four"
一下

2

vim宏(用q记录)可以应用您的操作,然后跳过三行。然后,您只需运行该宏n次。

例如:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q

2

由于您要求使用Gedit解决方案,因此应该可以执行以下操作:

找:

(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+

用。。。来代替:

\1\t\2\t\3\t\4\n

确保已选中正则表达式复选框。

怎么运行的:

第一步是使用\ w +查找一系列单词字符,并通过在表达式两边加上括号来捕获变量\ 1中的结果:

(\w+)

接下来,我们搜索一系列行尾字符\ r和\ n或CR和LF。由于Windows格式化文件同时使用这两种格式,因此我们通过将这两个字符包装在方括号中来创建字符类。加号使其搜索一个或多个字符:

[\r\n]+

最后,我们再重复3次,将每个后续单词存储在变量\ 2,\ 3和\ 4中。这使我们替换表达式变得简单。我们只需要在适当的位置放置制表符\ t和换行符\ n即可用于所需的格式设置。

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.