![一行中单词的笛卡尔积](https://linux22.com/image/894192/%E4%B8%80%E8%A1%8C%E4%B8%AD%E5%8D%95%E8%AF%8D%E7%9A%84%E7%AC%9B%E5%8D%A1%E5%B0%94%E7%A7%AF.png)
我有一个输入文件名“a”,其中包含如下数据:
BHARAT,SELXG,SAAB|ABCI
BHARAT,HONEY,HIRO,ABBS|XYZQ
我的预期输出是:
BHARAT|ABCI
SELXG|ABCI
SAAB|ABCI
BHARAT|XYZQ
HONEY|XYZQ
HIRO|XYZQ
ABBS|XYZQ
我已经使用过:perl -pe 's/,/\n/g' a
- 但没有给出预期的输出。
有人可以帮帮我吗?
答案1
由于您标记了您的问题perl
,因此这里有几种使用该语言进行回答的方法:
拆分和合并
$ perl -F'\|' -alne 'print join "|", $_, $F[1] for split ",", $F[0]' a BHARAT|ABCI SELXG|ABCI SAAB|ABCI BHARAT|XYZQ HONEY|XYZQ HIRO|XYZQ ABBS|XYZQ
分割和映射
$ perl -F'\|' -alne 'print for map { "$_|$F[1]" } split ",", $F[0]' a BHARAT|ABCI SELXG|ABCI SAAB|ABCI BHARAT|XYZQ HONEY|XYZQ HIRO|XYZQ ABBS|XYZQ
答案2
有很多方法可以实现。下面是使用awk
cat a | awk -F"[,|]" '{for (i=1;i<NF;i++) print $i"|"$NF}'
在终端,
$ cat a
BHARAT,SELXG,SAAB|ABCI
BHARAT,HONEY,HIRO,ABBS|XYZQ
$ cat a | awk -F"[,|]" '{for (i=1;i<NF;i++) print $i"|"$NF}'
BHARAT|ABCI
SELXG|ABCI
SAAB|ABCI
BHARAT|XYZQ
HONEY|XYZQ
HIRO|XYZQ
ABBS|XYZQ
怎么运行的:
,
读取以和作为分隔符的一行|
。- 打印一行中的每一列,然后打印该行中最后一列,并以
|
分隔符结尾。
答案3
Python 替代方案:
一句话:
python3 -c "for l in open('f'): d = l.strip().split('|');[print('|'.join([s, d[1]])) for s in d[0].split(',')]"
'f'
您的文件路径在哪里,用(单)引号引起来。
输出:
BHARAT|ABCI
SELXG|ABCI
SAAB|ABCI
BHARAT|XYZQ
HONEY|XYZQ
HIRO|XYZQ
ABBS|XYZQ
或者更具可读性:
#!/usr/bin/env python3
import sys
# open the file
for l in open(sys.argv[1]):
# remove spaces from the line(s), split by "|"
d = l.strip().split('|')
# list the first part of the line, join each of the items with the second part of the line
[print('|'.join([s, d[1]])) for s in d[0].split(',')]
使用
- 将脚本复制到一个空文件中,另存为
reorganize.py
通过命令运行:
python3 /path/to/reorganize.py /path/to/file_a
解释:
剧本:
打开文件,按行读取:
for l in open(sys.argv[1]):
按分隔符拆分行
|
,删除尾随的\n
d = l.strip().split('|')
使用分隔符“,”将第一部分拆分,列出其项目:
d[0].split(',')
,并将每个项目与行的最后一部分连接起来print('|'.join([s, d[1]]))
::[print('|'.join([s, d[1]])) for s in d[0].split(',')]