Как выборочно скопировать детали из файла и вставить их в новый файл?

11

У меня есть файл, содержащий мои личные данные (.txt). Как я могу через терминал скопировать только несколько деталей из файла и поместить их в новый .txtфайл?

Например, если это содержимое файла:

name : farah age : 23 phone number : 0123 education : degree

как я могу скопировать только возраст и номер телефона и вывести их в новый .txtфайл?

MsWanie
источник
2
Это зависит от того, что вы хотите скопировать в новый файл. Вы хотите, чтобы первые несколько строк, последние несколько, строки, содержащие строку, не содержащую строку, строки между двумя строками? Для этого есть инструменты, но нам нужно знать, что вы хотите сделать.
Arcege

Ответы:

7

Есть несколько способов сделать это. Если ваш файл имеет некоторую известную структуру, вы можете использовать grep. Команда grepищет в файле определенную фразу и возвращает строки, соответствующие этой фразе. Так что если ваш файл выглядит

Имя: Салли

Дата рождения: 7.31.76

Адрес: 1234 Main St.

SSN: 123-45-6789

Вы можете бежать, grep Name info.txtи он вернется Name: Sally. Затем вы можете перенаправить вывод в другой файл. Так зовет

grep Name info.txt > info2.txt

выведет строку в новый файл info2.txt. Если вы хотите добавить новые строки, вы можете сделать

grep Address info.txt >> info2.txt

в противном случае файл будет перезаписан.

Вы также можете научиться использовать текстовый редактор командной строки, как vim.

Крис Харпер
источник
2

Вы можете использовать grep для поиска регулярного выражения в файле details.txt и перенаправить результат в новый файл.

Если у всех строк, которые вы хотите скопировать, есть что-то общее, другие строки использовать нельзя:

grep "string in common" details.txt > new.txt

Если вы не придется искать для каждой линии , которую вы хотите скопировать, все еще используя Grep, и добавить их к new.txt , используя >>в смену >.

danjjl
источник
1

Есть также редакторы, которые работают в терминале, например, nano, vi и emacs.

Если вы используете графический интерфейс пользователя на своем локальном компьютере и терминал на удаленном компьютере, вы также можете использовать мышь для копирования и вставки из одного окна / вкладки терминала во второе.

elmicha
источник
1

Предполагая, что входной файл details.txtсодержит:

name: farah
age: 23
phone number: 0123
education: degree

Вы можете выбрать строки «имя» и «телефон» с помощью расширенного grep и перенаправить вывод в new.txt:

grep -E "age:|phone number:" details.txt > new.txt

Это создаст new.txt с:

age: 23
phone number: 0123

Как это устроено:

Grep печатает только совпадающие линии. В -Eопции включен расширенный регулярное выражение, что дает вам возможность использовать |(альтернатива). Не забудьте процитировать весь шаблон, поэтому |будет интерпретироваться grep. В противном случае оболочка попытается интерпретировать. Вы не хотите этого здесь.

Михал Шрайер
источник
1

Файл, который вы показали, содержит все детали в одной строке:

name : farah age : 23 phone number : 0123 education : degree

Я предположил, что вы можете жестко закодировать и age :т. Д. В команду, но текст, следующий за ней, будет отличаться, и что детали могут быть не в указанном порядке или быть смежными.

Вы можете извлечь части строки с grep«S -oфлага. Это печатает только соответствующую часть, а не всю линию.

Если вы хотите включить age :и phone number :части, вы можете использовать -eфлаг, чтобы указать несколько совпадений, или чередование.

$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123

Выражение [^ ]*означает любое количество символов, которые не являются пробелами, поэтому оно соответствует символам после age :следующего пробела.

Замените fileна имя файла, который содержит ваши данные. Вы можете написать новый файл, перенаправив вывод в новый файл с >оператором, например так:

grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile

Когда вы это сделаете, вы не увидите никакого вывода. Сначала вы должны проверить вывод, а затем добавить перенаправление.

Вот пример с чередованием. Мы используем -Eфлаг, чтобы указать grepиспользовать расширенное регулярное выражение. Синтаксис (pattern1|pattern2)- это соответствует pattern1и / или pattern2. Если один из них найден, он будет напечатан (независимо от того, найден другой или нет). Сейчас я использую +значение по крайней мере одного из предшествующих символов вместо *значения ноль или более от предыдущего символа. В этом контексте они оба работают одинаково хорошо.

$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23 
phone number : 0123 

Если вы хотите , чтобы опустить age :и phone number:детали, вы можете использовать -Pфлаг , чтобы попросить grepиспользовать Perl-совместимые регулярные выражения. Это поддерживает чередование, а также способ сопоставления текста по заданному шаблону:

$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123

Если вы хотите отформатировать текст по-другому, вы можете использовать sed, например:

$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123

Это зависит от ageтого phone number, что наступит раньше , поэтому отрегулируйте соответственно, если это не так. Если вы не можете положиться на порядок, вы можете использовать эту очень запутанную команду:

$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23

Это переставляет линию так, что phone number :сечение появляется первым в каждой строке, а затем выполняется вторая замена, чтобы выбрать нужные детали. Я обязан технике, использованной здесь, для этого ответа Муру .

Примечания к sedкомандам, не охваченным предыдущими пояснениями

  • -rиспользуйте расширенное регулярное выражение для более удобочитаемых команд (GNU sedпонимает -Eс тем же значением)
  • s/old/new/заменить oldнаnew
  • (pattern)сохраняет patternдля ссылки позже, с помощью \1или и \2т. д. (в соответствии с порядком слева направо, в котором встречаются группы захвата - обратите внимание, что они sedбудут содержать только до 7 из них!).
  • .любой символ, следовательно, .*представляет любое количество любых символов.
  • ; отделяет команды, как в оболочке.
Занна
источник