While executing,
$ls -1rt /directory | head -n 3
file1.txt
file2.txt
file3.txt
$ls -1rt /directory | tail -n 3
file2.txt
file3.txt
Could anyone tell me how the tail and head works internally during file listing and why this difference in no.of files?
Thanks in advance
head lists a certain amount of lines of your file. It won’t read it integraly, just the few first lines. tail does exactly the same thing, but starts at the end of the file. The -n 3 parameter is here to stop reading after 3 lines, then prints them only.
Related
This question already has answers here:
How can I use a file in a command and redirect output to the same file without truncating it?
(14 answers)
Closed 3 years ago.
I'm testing basic bash command on Ubuntu, when I put on terminal
wc -l < file1.txt > file2.txt
all lines from file1 are read by wc and the number is saved to file2.txt.
However if I use the similar command wc -l < file1.txt > file1.txt but I try to save it in the same > file1 the output is always 0.
What is the reason of this behavior ?
When you write the command wc -l < file1.txt > file1.txt, your shell will first read the command as a whole and redirect the standard input, output from/to file1.txt.
Then when a file is open for writing using >, if a file exists it will be overwritten and an empty file is created. the process (your wc) will then start its execution and it will write in it until the end of the execution.
Your wc -l will however have to read the file and count the number of lines in it, as the file is empty (overwritten) it will just dump in it:
0 file1.txt
To prove this look at what happens in appending mode using >>
$ cat file1.txt
a
b
b
$ wc -l file1.txt
3 file1.txt
$ wc -l file1.txt >> file1.txt
$ cat file1.txt
a
b
b
3 file1.txt
Your file content is intact and wc does properly read the number of lines before appending the result to the file.
Note:
In general, it is never recommended to write and read in the same file except if you know exactly what you are doing. Some commands have an inline option to modify the file during the run of the command and it is highly recommended to use them, as the file will not be corrupted even if the command crash in the middle of the execution.
Its because redirections have higher priority than other commands.
Here the file1 will be emptied before any operations can be performed on it
Try >> on file1.txt instead of >. >> will append to file unlike > overwriting whole file. Try -
wc -l < file1.txt >> file1.txt
I want to copy lines 10 to 15 of a file into another file in Unix.
I am having files file1.txt and file2.txt.
I want to copy lines 10 to 15 from file1.txt to file2.txt.
Open a terminal with a shell then
sed -n '10,15p' file1.txt > file2.txt
Simple & easy.
If you want to append to the end instead of wiping file2.txt, use >> for redirection.
sed -n '10,15p' file1.txt >> file2.txt
^^
AWK is also a powerful command line text manipulator:
awk 'NR>=10 && NR<=15' file1.txt > file2.txt
In complement to the previous answer, you can use one of the following 3 solutions.
sed
Print only the lines in the range and redirect it to the output file
sed -n '10,15p' file1.txt > file2.txt
head/tail combination
Use head and tail to cut the file and to get only the range you need before redirecting the output to a file
head -n 15 file1.txt | tail -n 6 > file2.txt
awk
Print only the lines in the range and redirect it to the output file
awk 'NR>=10 && NR<=15' file1.txt > file2.txt
I am looking to compare file1.txt contents with the last n file contents of file2.txt Can someone help in identifying this logic using anything in shell script.
Example if file1.txt has 10 lines, the last 10 lines of file2.txt should be compared for difference.
With bash's process substitution <() and command substitution $().
diff file1.txt <(tail -n $(wc -l < file1.txt) file2.txt)
I´d like to compare two files, but I don´t want to take into account the first 10 lines, and the last 3 lines of both files. I tried to do it with diff and tail commands, like in here, but without success.
how can I do it?
Use GNU tail and head:
To ignore the first 10 lines of a file, use tail like this:
tail -n +11 file
To ignore the last 3 lines of a file, use head like this:
head -n -4 file
You can then construct your diff command using process substitution as follows:
diff <(tail -n +11 file | head -n -4) <(tail -n +11 file2 | head -n -4)
I am using ls -l -t to get a list of files in a directory ordered by time.
I would like to limit the search result to the top 2 files in the list.
Is this possible?
I've tried with grep and I struggled.
You can pipe it into head:
ls -l -t | head -3
Will give you top 3 lines (2 files and the total).
This will just give you the first 2 lines of files, skipping the size line:
ls -l -t | tail -n +2 | head -2
tail strips the first line, then head outputs the next 2 lines.
To avoid dealing with the top output line you can reverse the sort and get the last two lines
ls -ltr | tail -2
This is pretty safe, but depending what you'll do with those two file entries after you find them, you should read Parsing ls on the problems with using ls to get files and file information.
Or you could try just this
ls -1 -t | head -2
The -1 switch skips the title line.
You can use the head command to grab only the first two lines of output:
ls -l -t | head -2
You have to pipe through head.
ls -l -t | head -n 3
will output the two first results.
Try this:
ls -td -- * | head -n 2