How can I remove specific characters in certain lines in a file? - unix

How do I cut characters from column 5 to 7 of the lines 3 onwards?
I am trying to use sed/cut.
For example, If I have
this is amazing1 this is amazing11
this is amazing2 this is amazing21
this is amazing3 this is amazing31
this is amazing4 this is amazing41
this is amazing5 this is amazing51
this is amazing6 this is amazing61
this is amazing7 this is amazing71
Output should look like:
this is amazing1 this is amazing11
this is amazing2 this is amazing21
this amazing3 this is amazing31
this amazing4 this is amazing41
this amazing5 this is amazing51
this amazing6 this is amazing61
this amazing7 this is amazing71
The characters is are removed from lines 3 and onwards.

sed -E '3,$s/(....).../\1/' file

I'd just use awk for clarity, portability, etc.:
$ awk 'NR>2{$0=substr($0,1,4) substr($0,8)} 1' file
this is amazing1 this is amazing11
this is amazing2 this is amazing21
this amazing3 this is amazing31
this amazing4 this is amazing41
this amazing5 this is amazing51
this amazing6 this is amazing61
this amazing7 this is amazing71
or using variables populated with the values from your question:
$ awk -v n=3 -v beg=5 -v end=7 'NR>=n{$0=substr($0,1,beg-1) substr($0,end+1)} 1' file
this is amazing1 this is amazing11
this is amazing2 this is amazing21
this amazing3 this is amazing31
this amazing4 this is amazing41
this amazing5 this is amazing51
this amazing6 this is amazing61
this amazing7 this is amazing71

In two steps:
head -n2 infile; tail -n+3 infile | cut --complement -c5-7
The first command prints the first two lines unmodified; the second command pipes the lines starting with the third one to cut, where character 5 to 7 are removed (requires GNU cut).
If you need to do something with the output, like store it in a file, you have to group these commands before redirecting:
{
head -n2 infile
tail -n+3 infile | cut --complement -c5-7
} > outfile

If you want to use sed:
sed '1,2!s/^\(\w*\)\s*\w*\(.*\)$/\1\2/' file
DETAILS
1,2!s - Don't do substitutions on line 1 and 2.
/^\(\w*\)\s*\w*\(.*\)$/ - The matching pattern.
/\1\2/ - Restore the groups of 1 and 2.
file - Your input file.

Related

No way to move pound (£) symbol in UNIX?

Need get the delimiters at the starting of each line, below are sample input and output files for reference. In actual Delimiter used are( £{, ^$^)
Note - The file to be rearranged has huge data
Have tried the below but it does not work:
tr £{ \\n
sed 's/£{/\n/g'
awk '{ gsub("£{", "\n") } 1'
Input File:
£{firstlinecontinues£{secondstartsfromhereandit
keepsoncontinueingtillend£{herecomes3rdand£{fi
nallyfourthisalsohere
Output File:
£{firstlinecontinues
£{secondstartsfromhereanditkeepsoncontinueingtillend
£{herecomes3rdand
£{finallyfourthisalsohere
With GNU awk for multi-char RS and \s:
$ awk -v RS='£{' 'NR>1{gsub(/\s/,""); print RS $0}' file
£{firstlinecontinues
£{secondstartsfromhereanditkeepsoncontinueingtillend
£{herecomes3rdand
£{finallyfourthisalsohere
awk 'BEGIN{RS="(£{\|\^\$\^)"; OFS=ORS=""}{$1=$1;print $0 (FNR>1?"\n":"") RT}' file
Since the £ symbol is represented by two Octal codes, 302 and 243, I was able to produce the desired result with this perl command:
perl -pe 's/(\302\243)/\n$1/g' data.txt
NOTE: Here's what I see on my system:
echo "£" | od -c
0000000 302 243 \n
0000003

Awk command in paragraph mode but skipping blank lines

I have one file with several elements <elem>...</elem>. I need to split this file into n files with m elements each one (argument passed to awk command I am using). For example if my original file has 40 elements, I would want to split in 3 files (10 elements, 13 elements and 17 elements).
The problem is that the original file has elements with different structures.
EDITED AFTER fedorqui comment:
I use as awk command as files I want to get at the end of the process.
That means If I need 3 files with m1, m2 and m3 elements, I will
execute 3 awk with different parameters
Example of input (file.txt) (5 elements)
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
<elem>ccccc
cccc</elem>
As you can see, 1st/2nd/4th element is in one line, 3rd element is in 3 lines without blank lines and 5h element is in 3 lines with an blank line.
Blank lines between elements is not a problem but blank lines inside an element fails
Example of desired output:
file_1.txt (2 elements)
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
file_2.txt (2 elements)
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
file_3.txt (1 element)
<elem>ccccc
cccc</elem>
AWK command
(suffixFile is the suffix number of the file. For example fileAux_1.txt, fileAux_2.txt...)
Attempt1
awk -v numElems=$1 -v suffixFile=$2 '{
for(i=1;i<=numElems;i++) {
printf "<doc>"$i > "fileAux_" suffixFile".txt"
}
}' RS='' FS='<doc>' file.txt
Works except for blank lines inside an element. I understand why it fails, because RS='' tells awk to split by blank lines
Attempt 2
awk -v numElems=$1 -v suffixFile=$2 '{
for(i=1;i<=numElems;i++) {
printf $i > "fileAux_" suffixFile".txt"
}
}' RS='<doc>' FS='<doc>' file.txt
Another aproach but it also fails
¿Can anyone help me?
Thanks in advance!
Assuming I understood your challenge correctly, here is my attempt:
$ cat script.sh
#!/bin/bash
awk -v numElems=$1 -v suffixFile=$2 '
/<elem>/{var++}
/<\/elem>/{var--; count++}
{if(count < numElems || (count == numElems && var == 0)) {
print $0 >> "file_"suffixFile".txt"
} else {
print $0
} }' $3
The script mainly keeps track of the <elem> and </elem> closures with the var and counts the pairs with count. Then an if statement decides whether to push the line to the file or not. Once the total number of elements is reached, the rest of the file is returned so you can reiterate the process using pipes.
Here is an example of how to run it with the final output:
$ ./script.sh 2 1 file.txt | ./script.sh 2 2 | ./script.sh 1 3
$ tail -n +1 file_*
==> file_1.txt <==
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
==> file_2.txt <==
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
==> file_3.txt <==
<elem>ccccc
cccc</elem>

to grep a pattern from file compare contents with another file and replace

I want to grep version number in one file and replace it in another file. I want to grep 4.3.0.5 in file 1 and replace it in File 2 at 4.3.0.2. I have the below command to get the number , but how can I cut/replace it in second file??
File1 :
App :4.3.0.5 (or) App: 4.3.0.5-SNAPSHOT
File2: Before editing
grid_application_distribution_url=nexus://com.abcd.efge.ce/App/4.3.0.2/tar.gz/config
File 2 : after editing (Desired Result:)
If $VERISON in File is WITHOUT the word SNAPSHOT then in file 2
grid_application_distribution_url=nexus://com.abcd.efge.ce/App/4.3.0.5/tar.gz/config
If $VERSION has SNAPSHOT then line in file 2 should be
grid_application_distribution_url=nexus-snapshot://com.abcd.efge.ce/App/4.3.0.5/tar.gz/config
VER=$(awk -F: '/^App/{sub(/ .*$/, "", $2); print $2}'/path/file1.txt)
echo $VER
if ($vER ~ /SNAPSHOT/)
/usr/bin/ssh -t -t server2.com "sub("=nexus:", ":=nexus-snapshot") /path/file2" && sub(/[^\/]+\/tar\.gz/, $VER"/tar.gz") /path/file2
Something like this is all you need:
awk -F': +' 'NR==FNR{v=$2;next} {sub(/[^/]+\/tar.gz/,v"/tar.gz")} 1' File1 File2 > tmp && mv tmp File2
This awk script can do the job (this is an enhancement of above answer from #EDMorton):
Splitting the command in 2 as per OP's request
VER=$(awk -F' *: *' '/^App/{print $2}' file1)
awk -v v="$VER" '{
split(v, arr, "-");
sub(/[^\/]+\/tar\.gz/, arr[1]"/tar.gz");
if (arr[2] ~ /SNAPSHOT/)
sub("=nexus:", ":=nexus-snapshot")
}1' file2 > tmpFile
mv tmpFile > file2
You can try with this:
VERSION=($(grep -r "App:" /path/File1| awk '{print ($2)}'))
sed -i "s/4.3.0.2/$VERSION/" File2
it will look for "4.3.0.2" and change by value in $VERSION. File2 will be updated with this change.
If you want the file to keep the same, delete the flag -i:
sed "s/4.3.0.2/$VERSION/" File2
You will get the result in stdout.
As indicated in comments, 4.3.0.2 is not like this every time. Adapted for format X.Y.Z.W:
sed "s/\/[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]\(\/tar.gz\)/\/$VERSION\1/" File2

Is there a way to ignore header lines in a UNIX sort?

I have a fixed-width-field file which I'm trying to sort using the UNIX (Cygwin, in my case) sort utility.
The problem is there is a two-line header at the top of the file which is being sorted to the bottom of the file (as each header line begins with a colon).
Is there a way to tell sort either "pass the first two lines across unsorted" or to specify an ordering which sorts the colon lines to the top - the remaining lines are always start with a 6-digit numeric (which is actually the key I'm sorting on) if that helps.
Example:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00
should sort to:
:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile
The parentheses create a subshell, wrapping up the stdout so you can pipe it or redirect it as if it had come from a single command.
If you don't mind using awk, you can take advantage of awk's built-in pipe abilities
eg.
extract_data | awk 'NR<3{print $0;next}{print $0| "sort -r"}'
This prints the first two lines verbatim and pipes the rest through sort.
Note that this has the very specific advantage of being able to selectively sort parts
of a piped input. all the other methods suggested will only sort plain files which can be read multiple times. This works on anything.
In simple cases, sed can do the job elegantly:
your_script | (sed -u 1q; sort)
or equivalently,
cat your_data | (sed -u 1q; sort)
The key is in the 1q -- print first line (header) and quit (leaving the rest of the input to sort).
For the example given, 2q will do the trick.
The -u switch (unbuffered) is required for those seds (notably, GNU's) that would otherwise read the input in chunks, thereby consuming data that you want to go through sort instead.
Here is a version that works on piped data:
(read -r; printf "%s\n" "$REPLY"; sort)
If your header has multiple lines:
(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)
This solution is from here
You can use tail -n +3 <file> | sort ... (tail will output the file contents from the 3rd line).
head -2 <your_file> && nawk 'NR>2' <your_file> | sort
example:
> cat temp
10
8
1
2
3
4
5
> head -2 temp && nawk 'NR>2' temp | sort -r
10
8
5
4
3
2
1
It only takes 2 lines of code...
head -1 test.txt > a.tmp;
tail -n+2 test.txt | sort -n >> a.tmp;
For a numeric data, -n is required. For alpha sort, the -n is not required.
Example file:
$ cat test.txt
header
8
5
100
1
-1
Result:
$ cat a.tmp
header
-1
1
5
8
100
So here's a bash function where arguments are exactly like sort. Supporting files and pipes.
function skip_header_sort() {
if [[ $# -gt 0 ]] && [[ -f ${#: -1} ]]; then
local file=${#: -1}
set -- "${#:1:$(($#-1))}"
fi
awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
}
How it works. This line checks if there is at least one argument and if the last argument is a file.
if [[ $# -gt 0 ]] && [[ -f ${#: -1} ]]; then
This saves the file to separate argument. Since we're about to erase the last argument.
local file=${#: -1}
Here we remove the last argument. Since we don't want to pass it as a sort argument.
set -- "${#:1:$(($#-1))}"
Finally, we do the awk part, passing the arguments (minus the last argument if it was the file) to sort in awk. This was orignally suggested by Dave, and modified to take sort arguments. We rely on the fact that $file will be empty if we're piping, thus ignored.
awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
Example usage with a comma separated file.
$ cat /tmp/test
A,B,C
0,1,2
1,2,0
2,0,1
# SORT NUMERICALLY SECOND COLUMN
$ skip_header_sort -t, -nk2 /tmp/test
A,B,C
2,0,1
0,1,2
1,2,0
# SORT REVERSE NUMERICALLY THIRD COLUMN
$ cat /tmp/test | skip_header_sort -t, -nrk3
A,B,C
0,1,2
2,0,1
1,2,0
Here's a bash shell function derived from the other answers. It handles both files and pipes. First argument is the file name or '-' for stdin. Remaining arguments are passed to sort. A couple examples:
$ hsort myfile.txt
$ head -n 100 myfile.txt | hsort -
$ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r
The shell function:
hsort ()
{
if [ "$1" == "-h" ]; then
echo "Sort a file or standard input, treating the first line as a header.";
echo "The first argument is the file or '-' for standard input. Additional";
echo "arguments to sort follow the first argument, including other files.";
echo "File syntax : $ hsort file [sort-options] [file...]";
echo "STDIN syntax: $ hsort - [sort-options] [file...]";
return 0;
elif [ -f "$1" ]; then
local file=$1;
shift;
(head -n 1 $file && tail -n +2 $file | sort $*);
elif [ "$1" == "-" ]; then
shift;
(read -r; printf "%s\n" "$REPLY"; sort $*);
else
>&2 echo "Error. File not found: $1";
>&2 echo "Use either 'hsort <file> [sort-options]' or 'hsort - [sort-options]'";
return 1 ;
fi
}
This is the same as Ian Sherbin answer but my implementation is :-
cut -d'|' -f3,4,7 $arg1 | uniq > filetmp.tc
head -1 filetmp.tc > file.tc;
tail -n+2 filetmp.tc | sort -t"|" -k2,2 >> file.tc;
Another simple variation on all the others, reading a file once
HEADER_LINES=2
(head -n $HEADER_LINES; sort) < data-file.dat
With Python:
import sys
HEADER_ROWS=2
for _ in range(HEADER_ROWS):
sys.stdout.write(next(sys.stdin))
for row in sorted(sys.stdin):
sys.stdout.write(row)
cat file_name.txt | sed 1d | sort
This will do what you want.

Removing trailing / starting newlines with sed, awk, tr, and friends

I would like to remove all of the empty lines from a file, but only when they are at the end/start of a file (that is, if there are no non-empty lines before them, at the start; and if there are no non-empty lines after them, at the end.)
Is this possible outside of a fully-featured scripting language like Perl or Ruby? I’d prefer to do this with sed or awk if possible. Basically, any light-weight and widely available UNIX-y tool would be fine, especially one I can learn more about quickly (Perl, thus, not included.)
From Useful one-line scripts for sed:
# Delete all leading blank lines at top of file (only).
sed '/./,$!d' file
# Delete all trailing blank lines at end of file (only).
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' file
Therefore, to remove both leading and trailing blank lines from a file, you can combine the above commands into:
sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba' file
So I'm going to borrow part of #dogbane's answer for this, since that sed line for removing the leading blank lines is so short...
tac is part of coreutils, and reverses a file. So do it twice:
tac file | sed -e '/./,$!d' | tac | sed -e '/./,$!d'
It's certainly not the most efficient, but unless you need efficiency, I find it more readable than everything else so far.
here's a one-pass solution in awk: it does not start printing until it sees a non-empty line and when it sees an empty line, it remembers it until the next non-empty line
awk '
/[[:graph:]]/ {
# a non-empty line
# set the flag to begin printing lines
p=1
# print the accumulated "interior" empty lines
for (i=1; i<=n; i++) print ""
n=0
# then print this line
print
}
p && /^[[:space:]]*$/ {
# a potentially "interior" empty line. remember it.
n++
}
' filename
Note, due to the mechanism I'm using to consider empty/non-empty lines (with [[:graph:]] and /^[[:space:]]*$/), interior lines with only whitespace will be truncated to become truly empty.
As mentioned in another answer, tac is part of coreutils, and reverses a file. Combining the idea of doing it twice with the fact that command substitution will strip trailing new lines, we get
echo "$(echo "$(tac "$filename")" | tac)"
which doesn't depend on sed. You can use echo -n to strip the remaining trailing newline off.
Here's an adapted sed version, which also considers "empty" those lines with just spaces and tabs on it.
sed -e :a -e '/[^[:blank:]]/,$!d; /^[[:space:]]*$/{ $d; N; ba' -e '}'
It's basically the accepted answer version (considering BryanH comment), but the dot . in the first command was changed to [^[:blank:]] (anything not blank) and the \n inside the second command address was changed to [[:space:]] to allow newlines, spaces an tabs.
An alternative version, without using the POSIX classes, but your sed must support inserting \t and \n inside […]. GNU sed does, BSD sed doesn't.
sed -e :a -e '/[^\t ]/,$!d; /^[\n\t ]*$/{ $d; N; ba' -e '}'
Testing:
prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n'
foo
foo
prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n' | sed -n l
$
\t $
$
foo$
$
foo$
$
\t $
$
prompt$ printf '\n \t \n\nfoo\n\nfoo\n\n \t \n\n' | sed -e :a -e '/[^[:blank:]]/,$!d; /^[[:space:]]*$/{ $d; N; ba' -e '}'
foo
foo
prompt$
using awk:
awk '{a[NR]=$0;if($0 && !s)s=NR;}
END{e=NR;
for(i=NR;i>1;i--)
if(a[i]){ e=i; break; }
for(i=s;i<=e;i++)
print a[i];}' yourFile
this can be solved easily with sed -z option
sed -rz 's/^\n+//; s/\n+$/\n/g' file
Hello
Welcome to
Unix and Linux
For an efficient non-recursive version of the trailing newlines strip (including "white" characters) I've developed this sed script.
sed -n '/^[[:space:]]*$/ !{x;/\n/{s/^\n//;p;s/.*//;};x;p;}; /^[[:space:]]*$/H'
It uses the hold buffer to store all blank lines and prints them only after it finds a non-blank line. Should someone want only the newlines, it's enough to get rid of the two [[:space:]]* parts:
sed -n '/^$/ !{x;/\n/{s/^\n//;p;s/.*//;};x;p;}; /^$/H'
I've tried a simple performance comparison with the well-known recursive script
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba'
on a 3MB file with 1MB of random blank lines around a random base64 text.
shuf -re 1 2 3 | tr -d "\n" | tr 123 " \t\n" | dd bs=1 count=1M > bigfile
base64 </dev/urandom | dd bs=1 count=1M >> bigfile
shuf -re 1 2 3 | tr -d "\n" | tr 123 " \t\n" | dd bs=1 count=1M >> bigfile
The streaming script took roughly 0.5 second to complete, the recursive didn't end after 15 minutes. Win :)
For completeness sake of the answer, the leading lines stripping sed script is already streaming fine. Use the most suitable for you.
sed '/[^[:blank:]]/,$!d'
sed '/./,$!d'
Using bash
$ filecontent=$(<file)
$ echo "${filecontent/$'\n'}"
In bash, using cat, wc, grep, sed, tail and head:
# number of first line that contains non-empty character
i=`grep -n "^[^\B*]" <your_file> | sed -e 's/:.*//' | head -1`
# number of hte last one
j=`grep -n "^[^\B*]" <your_file> | sed -e 's/:.*//' | tail -1`
# overall number of lines:
k=`cat <your_file> | wc -l`
# how much empty lines at the end of file we have?
m=$(($k-$j))
# let strip last m lines!
cat <your_file> | head -n-$m
# now we have to strip first i lines and we are done 8-)
cat <your_file> | tail -n+$i
Man, it's definitely worth to learn "real" programming language to avoid that ugliness!
#dogbane has a nice simple answer for removing leading empty lines. Here's a simple awk command which removes just the trailing lines. Use this with #dogbane's sed command to remove both leading and trailing blanks.
awk '{ LINES=LINES $0 "\n"; } /./ { printf "%s", LINES; LINES=""; }'
This is pretty simple in operation.
Add every line to a buffer as we read it.
For every line which contains a character, print the contents of the buffer and then clear it.
So the only things that get buffered and never displayed are any trailing blanks.
I used printf instead of print to avoid the automatic addition of a newline, since I'm using newlines to separate the lines in the buffer already.
This AWK script will do the trick:
BEGIN {
ne=0;
}
/^[[:space:]]*$/ {
ne++;
}
/[^[:space:]]+/ {
for(i=0; i < ne; i++)
print "";
ne=0;
print
}
The idea is simple: empty lines do not get echoed immediately. Instead, we wait till we get a non-empty line, and only then we first echo out as much empty lines as seen before it, and only then echo out the new non-empty line.
perl -0pe 's/^\n+|\n+(\n)$/\1/gs'
Here's an awk version that removes trailing blank lines (both empty lines and lines consisting of nothing but white space).
It is memory efficient; it does not read the entire file into memory.
awk '/^[[:space:]]*$/ {b=b $0 "\n"; next;} {printf "%s",b; b=""; print;}'
The b variable buffers up the blank lines; they get printed when a non-blank line is encountered. When EOF is encountered, they don't get printed. That's how it works.
If using gnu awk, [[:space:]] can be replaced with \s. (See full list of gawk-specific Regexp Operators.)
If you want to remove only those trailing lines that are empty, see #AndyMortimer's answer.
A bash solution.
Note: Only useful if the file is small enough to be read into memory at once.
[[ $(<file) =~ ^$'\n'*(.*)$ ]] && echo "${BASH_REMATCH[1]}"
$(<file) reads the entire file and trims trailing newlines, because command substitution ($(....)) implicitly does that.
=~ is bash's regular-expression matching operator, and =~ ^$'\n'*(.*)$ optionally matches any leading newlines (greedily), and captures whatever comes after. Note the potentially confusing $'\n', which inserts a literal newline using ANSI C quoting, because escape sequence \n is not supported.
Note that this particular regex always matches, so the command after && is always executed.
Special array variable BASH_REMATCH rematch contains the results of the most recent regex match, and array element [1] contains what the (first and only) parenthesized subexpression (capture group) captured, which is the input string with any leading newlines stripped. The net effect is that ${BASH_REMATCH[1]} contains the input file content with both leading and trailing newlines stripped.
Note that printing with echo adds a single trailing newline. If you want to avoid that, use echo -n instead (or use the more portable printf '%s').
I'd like to introduce another variant for gawk v4.1+
result=($(gawk '
BEGIN {
lines_count = 0;
empty_lines_in_head = 0;
empty_lines_in_tail = 0;
}
/[^[:space:]]/ {
found_not_empty_line = 1;
empty_lines_in_tail = 0;
}
/^[[:space:]]*?$/ {
if ( found_not_empty_line ) {
empty_lines_in_tail ++;
} else {
empty_lines_in_head ++;
}
}
{
lines_count ++;
}
END {
print (empty_lines_in_head " " empty_lines_in_tail " " lines_count);
}
' "$file"))
empty_lines_in_head=${result[0]}
empty_lines_in_tail=${result[1]}
lines_count=${result[2]}
if [ $empty_lines_in_head -gt 0 ] || [ $empty_lines_in_tail -gt 0 ]; then
echo "Removing whitespace from \"$file\""
eval "gawk -i inplace '
{
if ( NR > $empty_lines_in_head && NR <= $(($lines_count - $empty_lines_in_tail)) ) {
print
}
}
' \"$file\""
fi
Because I was writing a bash script anyway containing some functions, I found it convenient to write those:
function strip_leading_empty_lines()
{
while read line; do
if [ -n "$line" ]; then
echo "$line"
break
fi
done
cat
}
function strip_trailing_empty_lines()
{
acc=""
while read line; do
acc+="$line"$'\n'
if [ -n "$line" ]; then
echo -n "$acc"
acc=""
fi
done
}

Resources