11

I have a file containing my personal details (.txt). How can I via the terminal copy only a few details from the file and put those into a new .txt file?

For example, if this is the content of the file:

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

how can I copy only age and phone number and output those to a new .txt file?

1
  • 2
    It depends on what you want copied to the new file. Do you want the first few lines, the last few, lines containing a string, not containing a string, lines between two strings? There are tools to do all these, but we need to know what you wish to do.
    – Arcege
    Aug 31, 2011 at 17:04

5 Answers 5

7

There are several ways to do this. If your file has some known structure, you can use grep. The grep command searches a file for a specific phrase and returns lines that match that phrase. So if your file looks like

Name: Sally

Date of Birth: 7.31.76

Address: 1234 Main St.

SSN: 123-45-6789

you can run grep Name info.txt and it will return Name: Sally. You can then redirect the output to another file. So calling

grep Name info.txt > info2.txt

will output the line to the new file info2.txt. If you want to append new lines, you can do

grep Address info.txt >> info2.txt

otherwise the file will be overwritten.

You could also learn to use a command line text editor like vim.

2

You can use grep to search for a regular expression in details.txt and redirect the result to the new file.

If all the lines you want to copy have something in common the other lines don't you can use :

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

If not you will have to search for each line you want to copy, still using grep, and append them to new.txt using >> in stead of >.

0
2

The file you showed has all the details on one line:

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

I have assumed that you can hard-code age : etc into the command, but the text following it will vary, and that the details may not be in the given order or be contiguous.

You can extract parts of the line with grep's -o flag. This prints only the matched part, rather than the whole line.

If you want to include the age : and phone number : parts, you can either use the -e flag to specify multiple matches, or alternation.

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

The expression [^ ]* means any number of characters that are not a space, so it matches characters after age : up to the next space.

Replace file with the name of the file that contains your details. You may write the new file by redirecting the output to a new file with the > operator, like this:

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

When you do that, you won't see any output. You should check the output first, then add redirection.

Here's the example with alternation. We use the -E flag to tell grep to use extended regex. The syntax is (pattern1|pattern2) - this matches pattern1 and/or pattern2. If either is found, it will be printed (regardless of whether the other is found or not). I'm now using + meaning at least one of the preceding character, instead of * meaning zero or more of the preceding character. In this context, they both work equally well.

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

If you want to omit the age : and phone number: parts, you can use the -P flag to ask grep to use Perl-compatible regular expressions. This supports alternation, and also a way of matching text after a given pattern:

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

If you want to format the text differently, you can use sed, for example:

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

This depends on age coming before phone number, so adjust accordingly if that's not the case. If you can't rely on the order, you can use this very convoluted command:

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

This rearranges the line so that the phone number : section comes first on every line, then does a second replacement to select the desired details. I owe the technique used here to this answer by muru.

Notes on sed commands not covered by previous explanations

  • -r use extended regex for more readable commands (GNU sed understands -E with the same meaning)
  • s/old/new/ replace old with new
  • (pattern) saves pattern to reference later, with \1 or \2 etc (corresponding to the left-to-right order in which the capture groups occur - note that sed will only hold up to 7 of these!).
  • . any character, therefore .* represents any number of any characters.
  • ; separates commands, as in the shell.
1

There are also editors which work in the terminal, e.g. nano, vi and emacs.

If you are using a graphical user interface on your local machine and a terminal on a remote machine, you can also use the mouse to copy and paste from one terminal window/tab to a second one.

1

Assuming input file details.txt contains:

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

you can select lines "name" and "phone" by extended grep and redirect output to new.txt:

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

This will produce new.txt with:

age: 23
phone number: 0123

How it works:

Grep prints only matched lines. The -E options enabled extended regexp which gives you possibility to use | (alternative). Remember to quote whole pattern, so | will be interpreted by grep. Otherwise shell will try to interpret. You don't want this here.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .