【问题标题】:Pick up lines from a file based on line numbers in another file根据另一个文件中的行号从一个文件中提取行
【发布时间】:2017-11-10 23:03:27
【问题描述】:

我有两个文件 - 一个包含地址(行号),另一个包含数据,如下所示:

地址文件:

2
4
6
7
1
3
5

数据文件

1.000451451
2.000589214
3.117892278
4.479511994
5.484514874
6.784499874
7.021239396

我想根据地址文件的数量随机化数据文件 所以我得到:

2.000589214
4.479511994
6.784499874
7.021239396
1.000451451
3.117892278
5.484514874

我想在 python 或 bash 中执行此操作,但尚未找到任何解决方案。

【问题讨论】:

  • 地址文件是否包含行号或数据文件中的数字ints?
  • 只有行号
  • I want to do it either in python or in bash 然后尝试一下并添加有问题的代码...

标签: python bash awk


【解决方案1】:

如果您不介意sed,我们可以使用process substitution 轻松实现:

sed -nf <(sed 's/$/p/' addr.txt) data.txt
  • -n 禁止默认打印
  • -f 使 sed 从进程替换中读取命令 &lt;(...)
  • &lt;(sed 's/$/p/' addr.txt) 根据addr.txt 中的行号创建sed 打印命令

给出输出:

2.000589214
4.479511994
6.784499874
7.021239396
1.000451451
3.117892278
5.484514874

【讨论】:

    【解决方案2】:

    awk:

    awk 'NR==FNR {a[NR]=$0; next} {print a[$0]}' data.txt addr.txt
    
    • NR==FNR {a[NR]=$0; next} 创建一个关联数组 a,其中键是记录(行)编号,值是整个记录,这仅适用于第一个文件 (NR==FNR),即 @ 987654326@。 next 使awk 转到下一行而不进一步处理记录

    • {print a[$0]} 打印数组中的值,键为当前文件的 (addr.txt) 行(记录)编号

    示例:

    % cat addr.txt 
    2
    4
    6
    7
    1
    3
    5
    
    % cat data.txt 
    1.000451451
    2.000589214
    3.117892278
    4.479511994
    5.484514874
    6.784499874
    7.021239396
    
    % awk 'NR==FNR {a[NR]=$0; next} {print a[$0]}' data.txt addr.txt
    2.000589214
    4.479511994
    6.784499874
    7.021239396
    1.000451451
    3.117892278
    5.484514874
    

    【讨论】:

    • 很好的解决方案和很好的解释。
    • 在awk中使用非常灵活。
    • 质量不错的答案,并附有说明以供将来使用。 PS:我没有DV。
    【解决方案3】:

    您也可以在 Python 中执行此操作,例如以下示例:

    with open("address_file", 'r') as f1, open("data_file", "r") as f2:
        data1 = f1.read().splitlines()
        data2 = f2.read().splitlines()
    
    for k in data1:
        # Handle exceptions if there is any
        try:
            print(data2[int(k)-1])
        except Exception:
            pass
    

    编辑:正如@heemayl 建议的那样,这是另一种仅使用一个list 的解决方案:

    with open("file1", 'r') as f1, open("file2", 'r') as f2:
        data = f2.read().splitlines()
    
        for k in f1.read().splitlines():
            print(data[int(k)-1])
    

    两者都会输出:

    2.000589214
    4.479511994
    6.784499874
    7.021239396
    1.000451451
    3.117892278
    5.484514874
    

    【讨论】:

    • 您不需要有两个列表。只需为数据文件创建列表并仅使用行号遍历文件的行。
    • 是的,我知道。但我认为 OP 很容易捕捉到代码中发生的事情。我认为他不太了解如何使用 Python 回答他的问题。但是您的评论仍然是正确的。
    猜你喜欢
    • 1970-01-01
    • 2020-01-13
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多