LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 01-30-2012, 09:36 PM   #1
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Ubuntu
Posts: 1,032

Rep: Reputation: 275Reputation: 275Reputation: 275
Selecting lines based on position


I want to select lines based on their position (i.e. line number).

Sample of File1...
Quote:
Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Sample of File2...
Quote:
2
3
5
7
Desired output file...
Quote:
Alaska
Arizona
California
Connecticut
This can be done by using "nl" to number the lines in File1 and using "grep -f" but that seems like a brute force technique. Is there a clever and efficient way to do this?

Daniel B. Martin
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 01-30-2012, 11:01 PM   #2
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 608

Rep: Reputation: 352Reputation: 352Reputation: 352Reputation: 352
Hi.

Code:
# save to select.awk
BEGIN{
	getline
	file=FILENAME
	while(file == FILENAME){
		nums[$0]=1;
		getline
		}
}
(FNR in nums)
Provide a file with numbers as a first argument
Code:
$ awk -f select.awk numbers.txt file1.txt
Alaska
Arizona
California
Connecticut
 
1 members found this post helpful.
Old 01-31-2012, 08:02 AM   #3
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,178

Rep: Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779
Can be a little simpler:
Code:
awk 'FNR == NR{nums[$0];next}FNR in nums' numbers.txt file1.txt
 
2 members found this post helpful.
Old 01-31-2012, 12:43 PM   #4
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Ubuntu
Posts: 1,032

Original Poster
Rep: Reputation: 275Reputation: 275Reputation: 275
Quote:
Originally Posted by grail View Post
Code:
awk 'FNR == NR{nums[$0];next}FNR in nums' numbers.txt file1.txt
Thank you, grail, for this crisp solution. However, when tested with the sample data shown in the original post the output contained only three state names:
Quote:
Alaska
Arizona
California
Daniel B. Martin
 
Old 01-31-2012, 02:30 PM   #5
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,361

Rep: Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909
Apparently your samples above contain a trailing blank space at the end of the last line (after Georgia and 7 respectively). Therefore the last number is not treated as such, but as a literal string of two characters.

A slight modification to the grail's code should reveal the arcane:
Code:
awk 'FNR == NR{nums[$0+0];next}FNR in nums' numbers file
the +0 forces $0 to be treated as a number (the blank space is ignored) and the subsequent expression will match as expected.
 
1 members found this post helpful.
Old 02-01-2012, 01:50 AM   #6
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,178

Rep: Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779Reputation: 1779
Thanks for the fix colucix I often forget there can be other dodginess around
 
Old 02-01-2012, 02:06 AM   #7
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,361

Rep: Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909
Hi grail! That wasn't so obvious. I'd have never thought about that if I hadn't tried to copy/paste the sample input in a terminal.
 
Old 02-01-2012, 06:34 AM   #8
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
@colucix: Since the key is a line number, and thus integer, wouldn't nums[int($1)] be cleaner?

BTW, I did not know that array element reference was enough to define it. The GNU Awk manual does mention it -- A reference to an element that does not exist automatically creates that array element, with the null string as its value -- and not as specific to GNU awk. I just hadn't encountered that before. Useful; thanks!
 
1 members found this post helpful.
Old 02-01-2012, 07:20 AM   #9
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,361

Rep: Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909Reputation: 1909
Quote:
Originally Posted by Nominal Animal View Post
@colucix: Since the key is a line number, and thus integer, wouldn't nums[int($1)] be cleaner?
Indeed. It would be more cleaner and readable, especially for awk newbies. Thanks for the tip.
 
1 members found this post helpful.
Old 02-01-2012, 09:40 AM   #10
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Ubuntu
Posts: 1,032

Original Poster
Rep: Reputation: 275Reputation: 275Reputation: 275
Quote:
Originally Posted by colucix View Post
Apparently your samples above contain a trailing blank space at the end of the last line ...
Quite right, and I was unaware of this.

1) Thank you to everyone who contributed ideas, code, corrections, and comments to this thread. It is SOLVED!

2) I use gnome-terminal to browse a file. In this instance I was tripped by trailing blanks which are invisible to the unaided eye. I'd like to use a browser which distinguishes white space with a colored dot or some such. Is there a user setting for gnome-terminal which does this? Is there a different utility which can do this?

Daniel B. Martin
 
Old 02-01-2012, 09:58 AM   #11
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
The same technique can be done directly in bash too, Version 4's new mapfile built-in makes it particularly easy.

Code:
mapfile -t -O 1 states <file.txt

for i in 2 3 5 7; do
	echo "${states[i]}"
done
The -O option lets you set the starting index number, so you can store the first line as index 1 instead of the default 0, for one-to-one mapping.

For older bash versions, use a read loop to populate the array:
Code:
while IFS= read -r line; do
	states[++i]=$line
done < file.txt
Edit: One more solution using sed and a loop.

Code:
for i in 2 3 5 7; do
	sed -n "${i}p" file.txt
done
It's a bit more processor-intensive though, as it runs multiple commands.

Edit 2: Oh, but for just a simple list:

Code:
sed -n "2p; 3p; 5p; 7p"  file.txt

Last edited by David the H.; 02-01-2012 at 10:05 AM. Reason: as posted
 
  


Reply

Tags
awk, grep, linux, sed


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] SED search and replace fields in a fixed position based on a condition. jfkse7en Programming 7 01-06-2012 06:14 AM
Calculating new coordinates based on current position, bearing and speed Cotun Programming 14 04-06-2011 09:43 PM
Script to get position #s of first and last A-Z character on certain lines? kmkocot Programming 10 10-07-2010 09:21 AM
Text file manipulation: selecting specific lines/columns using awk and print CHARL0TTE Linux - Newbie 2 02-27-2010 02:40 AM
selecting few lines in perl vinaytp Linux - Newbie 4 06-20-2009 04:31 AM


All times are GMT -5. The time now is 12:04 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration