将同一行的两个字段放在一起

将同一行的两个字段放在一起

我遇到的情况是,我有几行,并且每行都需要两个不同的字段。具体来说,我有参考书目中的参考文献列表,我想获取姓氏和年份。

输入示例:

Aloise-Young, P.A. (1993). The development of self-presentation.  Self-promotion in 6- to 10-year-old children. Social Cognition, 11, 201-222.
Banerjee, R. (2002). Children's understanding of self-presentational behavior: Links with mental-state reasoning and the attribution of embarrassment. Merril-Palmer Quarterly, 48, 378-404.
Bennett, M., & Wellman, H. (1989). The role of second-order belief-understanding and social context in children's self-attribution of social emotions. Social Development, 9, 126-130.

期望的输出:

Aloise-Young 1993
Banerjee 2002
Bennett 1989

我可以得到姓氏cat file | cut -d, -f1

我可以得到岁月cat file | grep -o "[[:digit:]]\{4\}"

我的问题是,现在我有两个独立的输出,但我不知道如何以我想要的方式组合它们。有任何想法吗?我怀疑也许awk可以做我需要的事情。

答案1

当文本处理对于基本工具来说太困难时,请尝试awk

awk -F , '{last_name = $1; sub(/\).*/, ""); sub(/.*\(/, ""); print last_name, $0}'

sed 与此差不多——可读性较差,但 awk 缺乏反向引用。

sed -n 's/^\([^,]*\),[^(]*(\([^()]*\)).*/\1 \2/p'

对于这个特定的任务,Perl 总体上要容易一些。您可以使用非贪婪重复运算符*?来确保捕获该行的第一个括号部分。

perl -l -ne '/^([^,]*),.*?\(([^()]*)\)/ and print "$1 $2"'

答案2

我将您的代码片段放入名为 alois 的文件中:

sed -r 's/^([^ ,]+)[^0-9]+([0-9]+).*$/\1 \2/' alois 
Aloise-Young 1993
Banerjee 2002
Bennett 1989

快速解释:我们使用 sed 的搜索和替换功能s/模式/替换/

^([^ ,]+) 的意思是:从行的开头取出任何不是空格或 a 的内容,并记住它们。 (这就是括号的作用)。

[^0-9]+ 查找任何非数值的内容,但忽略它。

([0-9]+) 获取并记住任何连续数字

.*$ 将其他所有内容匹配到行尾。

\1 \2 将所有匹配的内容(整行)替换为上面记住的值。

答案3

一般来说,您可以将命令的输出与paste过程替换连接起来<(...),因此在您的情况下,这是可行的:

 paste -d ' ' <(cut -d, -f1 file) <(grep -o "[[:digit:]]\{4\}" file)

输出:

Aloise-Young 1993
Banerjee 2002
Bennett 1989

但这需要传递file两次,这是不必要的,因此您可能应该使用一种可以一次性抓取两个项目的工具,例如sedawk等。

答案4

不性感,但您可以将文本从第一个逗号修剪到第一个左括号。用空格替换所有内容。然后只需将字符从第一个右括号修剪到行尾即可。

1. convert this => , ..... ( to a space
2. convert this => )........ to nothing

命令

$ cat file | sed 's/,.*(/ /' | sed 's/).*//'
Aloise-Young 1993
Banerjee 2002
Bennett 1989

相关内容