我正在看一些 comments ,并试图决定最适合购买苹果的公司(例如).我复制并粘贴了下面的文本,我想用Linux命令对其进行一些文本处理.从我在网上读到的内容来看,awk是一个很好的 Select ,但我无法让它工作.

我try 取下有评级的行,并用逗号分隔将其附加到上面的行.例如:Abes Apples\n 4.1将变成Abes Apples, 4.1,并重复此过程.我测试的awk命令是awk 'BEGIN {RS=""}{gsub(/\n[0-9]/, ", ", $0); print $0}' test.text,它给出了下面的结果,但它正在替换数字.

Abes Apples, .1,
(138) · apple company, + years in business (123) 456-7890
Adams Apples, .9,
(105) · apple company, 0+ years in business (234) 567-8901
Apples are Amazing, .9,
(13) apple company, 0+ years in business (345) 678-9012

文本文件模式如下所示,并对文本文件中的所有行重复:

  1. 公司名称
  2. 额定值
  3. comments 数量和公司类型
  4. 营业年限和电话号码

我的目标是将这个文本文件转换成类似CSV的格式,其中我有公司名称、评级、 comments 数量(忽略‘Apple Company’文本)、经营年限和电话号码的列标题.这是否可以使用awk和其他Linux命令来完成?

Current Input:

Abes Apples
4.1,
(138) · apple company
7+ years in business (123) 456-7890
Adams Apples
4.9,
(105) · apple company
10+ years in business (234) 567-8901
Apples are Amazing
3.9,
(13) apple company
10+ years in business (345) 678-9012

Desired Output:

Abes Apples, 4.1,(138), 7, (123) 456-7890
Adams Apples, 4.9, (105), 10, (234) 567-8901
Apples are Amazing, 3.9, (13), 10, (345) 678-9012

推荐答案

另一种解析文件的通用方法是设置模式块,根据行在多行输入文件中的位置处理行,其中每个输出记录的信息都用连续的行分隔开,如OP的示例所示.

例如,在原始问题中,预期的输出记录需要跨越四行多行输入的信息.输入文件的公司名称位于第1、5、9、(...n+4)行,而评级信息位于第2、6、19行(...n+4).等.

因此,可以通过使用输入行号除以输入记录的重复图案大小(在这种情况下为4)的模除法判断行位置来建立块:

(NR-1)%4 == 0 { #code to apply to lines 1, 5, 9, ...n+4 }
(NR-2)%4 == 0 { #code to apply to lines 2, 6, 10, ...n+4 }
#etc.

如果从代码块中手动设置逗号和换行符,则可以简化CSV输出的格式化,因此可以使用BEGIN块来取消默认的换行符输出记录分隔符:

BEGIN {ORS=""}

这允许字段根据它们位于重复输入记录的哪一行而从不同的位置拉出.

替换也可以很容易地指向行,这可能会简化正则表达式的构造.例如,问题中的数据要求从第4、8、12的第一个字段中删除加号.N+4行,因此可以添加一个简单的替换模式来仅影响这些行.同样的行在最后一个和倒数第二个字段(保存代码和电话号码)中也有预期的输出.这些线路所需的块将变为:

(NR-4)%4 == 0 {sub(/\+/,"");print $1 ", " $(NF-1) " " $NF "\n"}

注意插入的(输出字段分隔)逗号和(输出记录分隔)新行.

整个awk命令可以在终端中逐行构建,而不需要将它们放在单独的脚本文件中:

awk 'BEGIN {ORS=""} 
(NR-1)%4 == 0 {print $0 ", "} 
(NR-2)%4 == 0 {print $0 " "} 
(NR-3)%4 == 0 {print $1 ", "} 
(NR-4)%4 == 0 {sub(/\+/,"");print $1 ", " $(NF-1) " " $NF "\n"}
' input.txt

或在简单情况下作为一行输入:

awk 'BEGIN {ORS=""} (NR-1)%4 == 0 {print $0 ", "} (NR-2)%4 == 0 {print $0 " "} (NR-3)%4 == 0 {print $1 ", "} (NR-4)%4 == 0 {sub(/\+/,"");print $1 ", " $(NF-1) " " $NF "\n"}' apples.txt

原始问题输入数据的输出:

Abes Apples, 4.1, (138), 7, (123) 456-7890
Adams Apples, 4.9, (105), 10, (234) 567-8901
Apples are Amazing, 3.9, (13), 10, (345) 678-9012

Linux相关问答推荐

使用Bash从文件名中删除日期名称

Git - 打印以不同编码混合的文件

8 个半小时范围的 Crontab 表达式

awk 不打印所需的 df 输出

Windows WSL 以上 Linux 中的 AF_UNIX 套接字无法绑定到 /mnt 文件:错误 95,不支持操作

如何使用 Bash 读取文件中的倒数第二行?

如何有效地使用 grep?

让 Tk 看起来像一个原生 Linux 应用程序

仅在不存在时添加换行符

zsh/bash 上不区分大小写的 Glob

如何搜索文件并将它们压缩到一个 zip 文件中

用于 ssh 的类似 teamviewer 的工具?

根据日期范围过滤日志(log)文件条目

C ++中套接字上的协议缓冲区

区分 Windows 和类 Unix 系统的 Makefile

在 bash 中将输出作为 cp 的参数传递

`cd //` 中的双斜杠 // 在 Linux 中是什么意思?

在 Linux 上更新 PyCharm

如何在 UNIX 中将字符串转换为整数

如何在我的终端中编辑文本文件