Строки человека доступа текстового файла и создают отдельный текстовый файл с тем именем

У меня есть два текстовых файла (сказать text1.txt и text 2.txt) оба с тем же количеством строк.напр. text1.txt содержит 4 записи

0127H
0132H
0982H
1772H

text2.txt содержит 4 записи

stev
mary
beautiful
ugly

Теперь моя задача состоит в том, чтобы создать 4 текстовых файла как

  • 0127H.txt содержать stev

  • 0132H.txt содержать mary

  • 0982H.txt содержать beautiful

  • 1772H.txt содержать ugly

Т.е. 1-я строка text1.txt должно быть имя файла, и соответствующая запись будет 1-й строкой text2.txt.

Я любезно запрашиваю Вас помочь мне избавиться от поднятого вопроса.

6
задан 1 May 2015 в 08:56

8 ответов

Следующая острота сделает то, в чем Вы нуждаетесь:

bash -c "$(paste text1.txt text2.txt | awk '{print "echo "$2">"$1".txt"}')"
2
ответ дан 23 November 2019 в 07:38

Это работало на меня:

c=1; while read f; do sed -n "${c}p" text2.txt >"$f.txt"; ((c++)); done <text1.txt

Это выполняет итерации канавки каждая строка в файле text1.txt. Тогда для каждой строки sed извлечения соответствующая строка в файле text2.txt и записях это к, что файл с .txt добавленный.

1
ответ дан 23 November 2019 в 07:38

Я могу сделать это со следующим сценарием удара:

#!/bin/bash

FILENAME="$1"
count=0
while read LINE
do
  let count++
  sed -n "$count"p text2 > "$LINE".txt
done < "$FILENAME"
0
ответ дан 23 November 2019 в 07:38

С awk, можно сделать:

awk 'FNR == NR {filename[FNR] = $0 ".txt"} FNR != NR {print > filename[FNR]}' file1 file2
  • FNR == NR тесты, читаем ли мы первый файл. Если это так, мы сохраняем строку в массиве.
  • Когда мы читаем второй файл, мы поиск соответствующее значение массива и использование что как выходной файл.
3
ответ дан 23 November 2019 в 07:38

Другая опция Python:

#!/usr/bin/env python3
import sys

lines = lambda f: open(f).read().splitlines()
content = lines(sys.argv[2])

for i, item in enumerate(lines(sys.argv[1])):
    open(item+".txt", "wt").write(content[i])

Это создаст обозначенные файлы в каталоге, откуда Вы запускаете скрипт

  • Сохраните его как combine.py
  • выполните его с командой:

    python3 /path/to/combine.py <file1> <file2>
    

Править

Как предложено @queueoverflow, с помощью zip опция (очень аккуратный, еще короче):

#!/usr/bin/env python3
import sys

lines = lambda f: open(f).read().splitlines()
for item, content in zip(lines(sys.argv[1]), lines(sys.argv[2])):
    open(item+".txt", "wt").write(content)

ИЛИ

Только для забавы; включая sys.argv[n] в функции лямбды, уменьшая его немного далее:

#!/usr/bin/env python3
import sys

lines = lambda n: open(sys.argv[n]).read().splitlines()
[open(f+".txt", "wt").write(c) for f, c in list(zip(lines(1), lines(2)))]
2
ответ дан 23 November 2019 в 07:38

Вот моя попытка этой задачи:

Шаг 1 - создает список всех текстовых файлов, Вы хотите иметь одно слово. Названный моим list, и один perline перечислил text1, text2, text3, и text4

Шаг 2 - Создает список слов, один на строку. Мой называют word

Шаг 3 - выполняет следующую команду: pr -m -t words list | awk '{x=$2; print $1>x}'

Теперь, конечно, это не острота, но работало на меня. Мой список слов был one two three four, и теперь text1 имеет one, text2 имеет two, и т.д

Править:

Вот моя сырая попытка адресуемых пространств между словами в файле слов: перевести \n к другому символу и затем использованию, что символ как разделитель в awk. Я протестировал это с df | tr '\n' '@' | awk -F '@' '{for (i=1;i<5;i++) print $i > "file"i".txt" }'

Результат состоит в том, что я получил 4 различных файла с 4 последовательными строками от df команда. Замена df с cat words. Вот результат

enter image description here

И да, этот метод не прекрасен; что, если строка содержит @ посреди него или в конце. Но этот метод гибок - @ может быть заменен с чем-то еще. Кроме того, пользователь должен, вероятно, знать при попытке в файлы текста процесса, как они разграничены; хороший пример /etc/passwd, где поля разделяются : , и никто вслепую не ворвался обработка того файла, правильно?

0
ответ дан 23 November 2019 в 07:38

Можно выполнить в этом bash:

IFS=$'\n'
a=($(<text1.txt))
i=0
while read -r line; do
  echo "${line}" > "${a[i++]}"
done < text2.txt

IFS присвоение говорит bash рассматривать только новую строку как ограничителя слова. Если Вы не хотите, чтобы та установка влияла на you'r, выполняющий оболочку, Вы могли бы хотеть запустить новое bash экземпляр для все это, или сброс IFS впоследствии к его использованию по умолчанию IFS=$' \t\n'.

Следующая строка имеет две части. a=( 0127H 0132H 0982H 1772H ) сделал бы a массив с четырьмя записями. Но вместо того, чтобы перечислить записи дословно, мы заменяем содержанием файла там. $(…) обычно выполняет команду и расширяется до ее вывода, но с продвижением < там это ведет себя почти, как будто команда была cat, т.е. это расширяется до содержания того файла. Вывод того файла разделяется на слова accoring к IFS, таким образом, строки, содержащие пробел, заканчиваются в элементе единого массива.

Затем мы циклично выполняемся по строкам text2.txt, и используйте счетчик i определить элемент соответствия text1.txt. Мы могли также загрузиться text2.txt как массив, и затем выполняют итерации по обоим массивам параллельно, особенно после проверки, что их длины соглашаются.

IFS=$'\n'
a=($(<text1.txt))
b=($(<text2.txt))
if [[ ${#a[@]} -ne ${#b[@]} ]]; then
  echo "Length mismatch" >& 2
else
  for ((i=0; i<${#a[@]}; ++i)); do
    echo "${b[i]}" > "${a[i]}"
  done
fi
0
ответ дан 23 November 2019 в 07:38

Сохраните ниже сценария Python как files.py или подобный. Можно найти его здесь

#!/usr/bin/python3

# -*- coding: utf-8 -*-
# Copyright © 2015 Martin Ueding <dev@martin-ueding.de>    
# Licensed under The MIT License

import argparse


def main():

    options = _parse_args()
    with open(options.first) as f:    
        lines1 = [s.strip() for s in f.readlines()]    
    with open(options.second) as f:    
        lines2 = f.readlines()    
    for first, second in zip(lines1, lines2):    
        with open(first + '.txt', 'w') as f:    
            f.write(second)


def _parse_args():    
    '''    
    Parses the command line arguments.            
    :return: Namespace with arguments.    
    :rtype: Namespace    
    '''

    parser = argparse.ArgumentParser(description='')    
    parser.add_argument('first')    
    parser.add_argument('second')    
    options = parser.parse_args()             
    return options        


if __name__ == '__main__':    
    main()

Затем можно запустить его с

python3 files.py text1.txt text2.txt

и это генерирует все файлы, которые Вы хотите.


Преимущества этого решения:

  • Это работает, если строки в файлах имеют пробелы или другие символы, которые рассматривают особенные в оболочке.
  • Код читаем, не зная набор ловушек в Bash.
  • В случае, если существует недостаточно параметра, передал командную строку, Вы получите читаемое сообщение об ошибке и вызов его с -h или --help также работает просто великолепно.
  • Это может иметь дело с DOS, и Mac OS разрабатывают разрывы строки (\n\r и \r).
  • Сценарий Python даже работал бы на Windows.
  • Это не пропускает дескрипторы файлов, так как это использует менеджеров по контексту (with …:).
0
ответ дан 23 November 2019 в 07:38

Другие вопросы по тегам:

Похожие вопросы: