Why does wc count one extra character in my file? [duplicate] - linux

This question already has an answer here:
wc -m in unix adds one character
(1 answer)
Closed 6 years ago.
1.) I am using Debian 8.4 on a virtual box and as I ran the command wc sample.txt to sample.txt containing:
Hello
The output to the command was
1 1 6 sample.txt
Is the extra character EOF? If it is then how come when I ran the same command for an empty file the output was..
0 0 0 sample.txt

You have a trailing new line and this is what wc reports.
See for example if we create a file with printf:
$ printf "hello" > a
$ cat a | hexdump -c
0000000 h e l l o
0000005
$ wc a
0 1 5 a
However, if we write with something like echo, a trailing new line is appended:
$ echo "hello" > a
$ cat a | hexdump -c
0000000 h e l l o \n
0000006
$ wc a
1 1 6 a

Related

Removing the new line in the last line of a text file using sed

I wanna remove the new line in the last line of my text file using sed. For example the input is like the following:
1
1
1
1
1
1
And I want to have an output like this without any new lines at the end of the text file:
1
1
1
1
1
1
This might work for you (GNU sed):
sed -z 's/\n\+$//' file
This will remove a newline(s) at the end of a file provided there are no null characters.
N.B. Normal use of sed i.e. without the -z option which slurps the file into memory, will remove any newlines before the sed commands can act on them.
Using sed
sed '/^$/d' input_file
This will remove all empty lines
Starting with some test data:
$ printf "%s\n" {a..e} "" "" | cat -n
1 a
2 b
3 c
4 d
5 e
6
7
I would approach the problem like this: reverse the file, remove blank lines
at the top, then re-reverse the file
$ printf "%s\n" {a..e} "" "" | tac | awk 'NF && !p {p=1}; p' | tac | cat -n
1 a
2 b
3 c
4 d
5 e
NF is the awk variable for "number of fields in this record". p is a variable I'm using to indicate when to start printing. The first time that NF is non-zero, we set the p variable to a true value. The standalone p at the end triggers the default action to print the record.
Removing the newline on the last line is a different story.
Given this file:
$ cat > file
first
second
third
$ od -c file
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d \n
0000023
We can use perl:
$ perl -i -0777 -ne 's/\n+$//; print' file
$ od -c file
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d
0000022
or tr to translate newlines to some other character, and sed to remove the trailing character
$ tr '\n' '\034' < file | sed $'s/\034$//' | tr '\034' '\n' | od -c
0000000 f i r s t \n s e c o n d \n t h i
0000020 r d
0000022

Bash simple search script with individual results [duplicate]

This question already has answers here:
How to grep for the whole word
(7 answers)
Closed 3 years ago.
I have a script that searches through a file and displays the results.
However there is a problem for example when i search 1 the following results are given:
1 B C
11 D E
12 B C
13 D E
When i search for 1, I only want it to show the 1 not also
11 D E
12 B C
13 D E
Is this possible?
echo "$#" | sed 's/[[:space:]]/.*/g' | xargs -Ifile grep -Ei 'file' text.txt
You can use :
grep -w "1" <filename>
Explaination:
-w, --word-regexp
The expression is searched for as a word
Output without w:
grep "1" abc.txt
1
12
13
111
123
312
412
Output with w:
grep -w "1" abc.txt
1
When content of abc.txt is :
1
12
13
111
123
312
412
Try this in the script:
grep -o "\b$1\b" <file_name>
Example
vals=1
cat word.txt
1 B C
11 D E
12 B C
13 D E
grep -o "\b${vals}\b" word.txt
1
You can use -w flag with grep command. Please check the screenshot below.

How to print lines between 2 values using tail & head and pipe?

For example:how can I print specific lines of a .txt file between line 5 and line 8 using only tail and head
Copied from here
infile.txt contains a numerical value on each line.
➜ X=3
➜ Y=10
➜ < infile.txt tail -n +"$X" | head -n "$((Y - X))"
3
4
5
6
7
8
9
➜

How to read n-th line from a text file in bash?

Say I have a text file called "demo.txt" who looks like this:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now I want to read a certain line, say line 2, with a command which will look something like this:
Line2 = read 2 "demo.txt"
So when I'll print it:
echo "$Line2"
I'll get:
5 6 7 8
I know how to use 'sed' command in order to print a n-th line from a file, but not how to read it. I also know the 'read' command but dont know how to use it in order a certain line.
Thanks in advance for the help.
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 patternspace
input 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.
Perl has convenient support for this, too, and it's actually the most intuitive!
The flip-flop operator can be used with line numbers:
$ printf "0\n1\n2\n3\n4" | perl -ne 'printf if 2 .. 4'
1
2
3
Note that it's 1-based.
You can also mix regular expressions:
$ printf "0\n1\nfoo\n3\n4" | perl -ne 'printf if /foo/ .. -1'
foo
3
4
(-1 refers to the last line)

Move Last Four Lines To Second Row In Text File

I need to move the last 4 lines of a text file and move them to the second row in the text file.
I'm assuming that tail and sed are used but, I haven't much luck so far.
Here is a head and tail solution. Let us start with the same sample file as Glenn Jackman:
$ seq 10 >file
Apply these commands:
$ head -n1 file ; tail -n4 file; tail -n+2 file | head -n-4
1
7
8
9
10
2
3
4
5
6
Explanation:
head -n1 file
Print first line
tail -n4 file
Print last four lines
tail -n+2 file | head -n-4
Print the lines starting with line 2 and ending before the fourth-to-last line.
If I'm assuming correctly, ed can handle your task:
seq 10 > file
ed file <<'COMMANDS'
$-3,$m1
w
q
COMMANDS
cat file
1
7
8
9
10
2
3
4
5
6
lines 7,8,9,10 have been moved to the 2nd line
$-3,$m1 means, for the range of lines from "$-3" (3 lines before the last line) to "$" (the last line, move them ("m") below the first line ("1")
Note that the heredoc has been quoted so the shell does not try to interpret the strings $- and $m1 as variables
If you don't want to actually modify the file, but instead print to stdout:
ed -s file <<'COMMANDS'
$-3,$m1
%p
Q
COMMANDS
Here is an awk solution:
seq 10 > file
awk '{a[NR]=$0} END {for (i=1;i<=NR-4;i++) if (i==2) {for (j=NR-3;j<=NR;j++) print a[j];print a[i]} else print a[i]}' file
1
7
8
9
10
2
3
4
5
6

Resources