Bash tool to get nth line from a file
head
and pipe with tail
will be slow for a huge file. I would suggest sed
like this:
sed 'NUMq;d' file
Where NUM
is the number of the line you want to print; so, for example, sed '10q;d' file
to print the 10th line of file
.
Explanation:
NUMq
will quit immediately when the line number is NUM
.
d
will delete the line instead of printing it; this is inhibited on the last line because the q
causes the rest of the script to be skipped when quitting.
If you have NUM
in a variable, you will want to use double quotes instead of single:
sed "${NUM}q;d" file
How do I read the Nth line of a file and print it to a new file?
Sed can help you.
Recall that sed will normally process all lines in a file AND print each line in the file.
You can turn off that feature, and have sed only print lines of interest by matching a pattern or line number.
So, to print the 2nd line of file 2, you can say
sed -n '2p' file2 > newFile2
To print the 2nd line and then stop processing add the q (for quit) command (you also need braces to group the 2 commands together), i.e.
sed -n '2{p;q;}' file2 > newFile2
(if you are processing large files, this can be quite a time saving).
To make that more general, you can change the number to a variable that will hold a number, i.e.
lineNo=3
sed -n "${lineNo}{p;q;}" file3 > newFile3
If you want all of your sliced lines to go into 1 file, then use the shells 'append-redirection', i.e.
for lineNo in 1 2 3 4 5 ; do
sed -n "${lineNo}{p;q;}" file${lineNo} >> aggregateFile
done
The other postings, with using the results of find ...
to drive your filelist, are an excellent approach.
I hope this helps.
How to read n-th line from a text file in bash?
Using head
and tail
$ head -2 inputFile | tail -1
5 6 7 8
OR
a generalized version
$ line=2
$ head -"$line" input | tail -1
5 6 7 8
Using sed
$ sed -n '2 p' input
5 6 7 8
$ sed -n "$line p" input
5 6 7 8
What it does?
-n
suppresses normal printing of pattern space.'2 p'
specifies the line number,2
or ($line
for more general),p
commands to print the current patternspaceinput
input file
Edit
To get the output to some variable use some command substitution techniques.
$ content=`sed -n "$line p" input`
$ echo $content
5 6 7 8
OR
$ content=$(sed -n "$line p" input)
$ echo $content
5 6 7 8
To obtain the output to a bash array
$ content= ( $(sed -n "$line p" input) )
$ echo ${content[0]}
5
$ echo ${content[1]}
6
Using awk
Perhaps an awk
solution might look like
$ awk -v line=$line 'NR==line' input
5 6 7 8
Thanks to Fredrik Pihl for the suggestion.
How to get the nth line from a file and save the result to a variable
sed '2q;d' file
prints the second line in file
to the terminal.
To populate a variable with it, use bash's command expansion feature:
$ var=$(sed '2q;d' file)
$ echo "$var"
this is second line
find text in file starting from nth line onwards, using shell script
It would be best to do this entirely in awk
since you are already using awk to slice the file.
Example:
tgt="def"
n=3
awk -v tgt="$tgt" -v n="$n" '
BEGIN{flag="false"}
FNR>=n && index($0,tgt){
flag="true"
exit
}
END{print flag}' file
Alternatively, you can make a pipe and then inspect $?
to see if grep
found your match:
tgt="def"
n=2
tail -n "+$n" file | grep "$tgt" >/dev/null
Now $?
will be 0
if the grep finds the pattern and 1
if it is not found. Then you can set a flag like so:
flag="false"
tail -n "+$n" file | grep "$tgt" >/dev/null
[ $? ] && flag="true"
Now flag
is set true / false based on the grep. The command tail -n +[some number] file
will print the file contents from the absolute line number onward.
For large files, the awk is significantly more efficient since it exits on the first match.
Edit based on update.
The issue is setting a Bash flag to true
or false
based on a process.
The $?
Special Parameter is set based on the exit status of the most recently executed foreground pipeline. So pick your method to slice the file and detect the string and then set the flag in your script based on $?
immediately after the pipe. Be aware that testing $?
resets $?
before it is tested -- so you either need to capture the value of $?
before the test or use it in the pipeline itself.
These methods work:
1) Capture $? and test:
awk -v tgt="$tgt" -v n="$n" -v flag=1 '
FNR>=n && index($0,tgt){
flag=0
exit
}
END{ exit flag }
' ./testtext.txt
res=$?
[ $res -eq 1 ] && flagz=false || flagz=true
2) Capture a string result and test that:
res=$(awk -v tgt="$tgt" -v n="$n" -v flag="false" '
FNR>=n && index($0,tgt) {
flag="true"
exit
}
END{ print flag }' ./testtext.txt)
[ $res = "false" ] && flagz=false || flagz=true
3) Use a pipe and test in the pipe:
tail -n "+$n" file | grep "$tgt" >/dev/null && flagz=true || flagz=false
My preference is 3 for small files and 2 for big files.
Get specific line from text file using just shell script
sed:
sed '5!d' file
awk:
awk 'NR==5' file
fetch nth line of a text file using non-interactive shell script
An efficient way to print nth line from a file (especially suited for large files):
sed '2q;d' file
This sed command quits just after printing 2nd line rather than reading file till the end.
To store this in a variable:
line=$(sed '2q;d' file)
OR using a variable for line #:
n=2
line=$(sed $n'q;d' file)
UPDATE:
Java Code:
try {
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "/full/path/of/myScript.sh" );
Process pr = pb.start();
InputStreamReader isr = new InputStreamReader(pr.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null)
System.out.println(line);
int exitVal = pr.waitFor();
System.out.println("exitVal: " + exitVal);
} catch(Exception e) { e.printStackTrace(); }
Shell script:
f=$(dirname $0)/edit.txt
read -r i < "$f"
echo "session is: $i"
echo -n "file path is: "
sed '2q;d' "$f"
how to print the nth line from the end of a file in bash?
The quick and easy way is tail -n $n file | head -n 1
.
A more fun way with awk
is:
awk -v n=$n '{x[NR%n]=$0}END{print x[(NR+1)%n]}' file
If you have fewer than n
lines, the tail | head
method will print the first line of the file, the awk
way will print a blank line.
Related Topics
How to Get Clock_Gettime(2) Clock in Shell
Tmux .Tmux.Conf Doesn't Load Properly
Emacs/Xterm Color Annoyance on Linux
Ffmpeg Install on Centos 64-Bit 'Install with -Fpic' Error
How Many Objects Are Returned by Aws S3API List-Objects
Shopify + Ubuntu 12.04Lts + Faraday Issue = Ok to Use Older Openssl
App Engine Ignores Symlinks to Directories
Can't Install The Caret Package in R (In My Linux Machine)
How to Delete The Line That Matches a Pattern and The Line After It with Sed
Difference Between .So.0 and .So.0.0.0 Files
Xmonad: Spawnon Workspace That Had Focus When Spawn Key Was Pressed
How to Copy from Tmux (Copy Mode) Running on a Remote Ssh Connection to Your Local Clipboard
Permission Denied: '/Var/Lib/Pgadmin/Sessions' in Docker
Unix/Linux Ipc: Reading from a Pipe. How to Know Length of Data at Runtime
Linux + Find Word in File Under Directory But Quickly
Javafx: Tested/Confirmed Hardware (Gpu) Acceleration on Linux