How to delete all lines with less then 32 characters from a textfile?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting How to delete all lines with less then 32 characters from a textfile?
# 15  
Old 02-26-2010
Quote:
Originally Posted by alister
Did you test it with filenames containing IFS characters? Assuming a default IFS value, your option handling, sed invocations, and cat statement will all barf if a filename contains whitespace.

Code:
for opt in $*

should be
Code:
for opt in "$@"

All instances of $3 need to be double-quoted.

Alister
Okay, I'll change that then.

EDIT: I fixed the script. It now looks like this:
Code:
#!/bin/bash
# deletes lines of a certain range length from a file
# Writing the result to the file is optional.

write="no";
for opt in "$@"
do
	case "$opt" in
		-w ) write="yes";
		     shift;;
		-* ) shift;;
		*  );;
	esac
done
least=$1;
great=$2;
shift;
shift;
filname="$*";
if [ $write == "yes" ]
then
	sed -e "/^.\{$least,$great\}$/d" "$filname" > tempfile.txt;
	cat tempfile.txt > "$filname";
	rm tempfile.txt;
else
	sed -e "/^.\{$least,$great\}$/d" "$filname";
fi
unset write

All I did was put quotation marks around the filename. I was also able to fix another script that I wrote a while back which was having the same problem.

Actually I've found I don't have to use "$@". It works whether I use that or $*. The quotation marks were the only problem.

Last edited by Ultrix; 02-26-2010 at 01:10 PM..
# 16  
Old 02-27-2010
Quote:
Originally Posted by Ultrix
Actually I've found I don't have to use "$@". It works whether I use that or $*. The quotation marks were the only problem.
If you aren't using "$@" in that situation, then your script has a bug. There is no doubt about it.

Using $@ without quotes or $* with or without quotes will not expand to each individual command line argument (positional parameter in sh man page lingo). If unquoted, $@ and $* behave identically; they will expand to a list of words and then (this is the problem) each word (a positional parameter at this point) will be split according to the current setting of IFS (after splitting, the words may no longer correspond to the positional parameters). If you quote $*, you end up with one word containing all your positional parameters, regardless of how many parameters there are.

In that for loop, "$@" is the only correct option. If you don't believe me, try $* or $@ with a file name containing a space (assuming default IFS value) followed by one of your program's valid options, such as "infile -w". Even if the -w option isn't passed, such a filename will trigger it because "infile -w" will be split into two words, "infile" and "-w". That would be a bug. I realize that's a contrived and unlikely filename, but the point is that the option handling is behaving erroneously.

If you don't see it, read the sh man page carefully, with particular emphasis on the special parameters $@ and $*, quoting, and word splitting.

Here's some exemplary code:
Code:
$ cat o.sh 
#!/bin/bash

printf '==================================================\n'
printf '$@: INCORRECT: Word splitting after $@ expansion yields 3 words.\n'
for opt in $*
do
        case "$opt" in
                *  )echo "$opt";;
        esac
done

printf '==================================================\n'
printf '$*: INCORRECT: Word splitting after $* expansion yields 3 words.\n'
for opt in $*
do
        case "$opt" in
                *  )echo "$opt";;
        esac
done

printf '==================================================\n'
printf '"$*": INCORRECT: Always expands to one word, regarless of $# positional parameter count.\n'
for opt in "$*"
do
        case "$opt" in
                *  )echo "$opt";;
        esac
done

printf '==================================================\n'
printf '"$@": CORRECT: Expands to one word per positional parameter without subsequent word splitting.\n'
for opt in "$@"
do
        case "$opt" in
                *  )echo "$opt";;
        esac
done

# Let's call the script with two positional parameters.
# Only "$@" will expand to the two correct words, while the others result in 1 or 3.

$ ./o.sh -v 'input -w'
==================================================
$@: INCORRECT: Word splitting after $@ expansion yields 3 words.
-v
input
-w
==================================================
$*: INCORRECT: Word splitting after $* expansion yields 3 words.
-v
input
-w
==================================================
"$*": INCORRECT: Always expands to one word, regarless of $# positional parameter count.
-v input -w
==================================================
"$@": CORRECT: Expands to one word per positional parameter without subsequent word splitting.
-v
input -w

I hope this helped.

Regards,
Alister

Last edited by alister; 02-27-2010 at 10:27 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Replicating certain lines in a textfile

I am very new to to shell scripting and facing a problem that I can't seem to solve. I want to write a bash script that edits file1.txt and saves it as file2.txt. This is what the files should look like: file1: textline1 textline2 startCopy copyThis endCopy textline3 textline4 file2: ... (6 Replies)
Discussion started by: sandy90
6 Replies

2. Shell Programming and Scripting

How to separate sorte different characters from one textfile and copy them in a new textfile?

My first post, so don't kill me :) Say i open some textfile with some example like this. on the table are handy, bread and wine Now i know exactly what is in and i want to separate and sorted it in terminal to an existing file with another 2 existing lines in like this: table plane ... (3 Replies)
Discussion started by: schwatter
3 Replies

3. Shell Programming and Scripting

Cut lines from and to in a textfile

i am having a text file like below rama surya pandu latha singh raja i want to get the new file from 3 to 5 i.e pandu latha singh please help (1 Reply)
Discussion started by: suryanarayana
1 Replies

4. Shell Programming and Scripting

Sed/awk to delete single lines that aren't touching other lines

Hello, I'm trying to figure out how to use sed or awk to delete single lines in a file. By single, I mean lines that are not touching any other lines (just one line with white space above and below). Example: one two three four five six seven eight I want it to look like: (6 Replies)
Discussion started by: slimjbe
6 Replies

5. Shell Programming and Scripting

search and replace, when found, delete multiple lines, add new set of lines?

hey guys, I tried searching but most 'search and replace' questions are related to one liners. Say I have a file to be replaced that has the following: $ cat testing.txt TESTING AAA BBB CCC DDD EEE FFF GGG HHH ENDTESTING This is the input file: (3 Replies)
Discussion started by: DeuceLee
3 Replies

6. UNIX for Advanced & Expert Users

In a huge file, Delete duplicate lines leaving unique lines

Hi All, I have a very huge file (4GB) which has duplicate lines. I want to delete duplicate lines leaving unique lines. Sort, uniq, awk '!x++' are not working as its running out of buffer space. I dont know if this works : I want to read each line of the File in a For Loop, and want to... (16 Replies)
Discussion started by: krishnix
16 Replies

7. Shell Programming and Scripting

Find a string in textfile, erase $num lines after that string

I have a textfile containing text similar to the following pattern: STRING1 UNIQUE_STRING1 STRING2 STRING3 STRING4 STRING5 STRING1 UNIQUE_STRING2 STRING2 STRING3 STRING4 STRING5 STRING1 UNIQUE_STRING3 STRING2 STRING3 (6 Replies)
Discussion started by: ilcsfe
6 Replies

8. UNIX for Dummies Questions & Answers

How get only required lines & delete the rest of the lines in file

Hiiii I have a file which contains huge data as a.dat: PDE 1990 1 9 18 51 28.90 24.7500 95.2800 118.0 6.1 0.0 BURMA event name: 010990D time shift: 7.3000 half duration: 5.0000 latitude: 24.4200 longitude: 94.9500 depth: 129.6000 Mrr: ... (7 Replies)
Discussion started by: reva
7 Replies

9. Shell Programming and Scripting

Detect lines beginning with double-byte characters (Japanese) and delete

Greetings, I want to use a script (preferably awk) which determines if the first character in a line is double-byte (as in Japanese or Chinese) and deletes it. For example: (in the above quote, I see Japanese on my screen for two lines - with 2 characters in the first and 3 characters in the... (8 Replies)
Discussion started by: ubbeauty
8 Replies

10. Shell Programming and Scripting

How to delete lines in a file that have duplicates or derive the lines that aper once

Input: a b b c d d I need: a c I know how to get this (the lines that have duplicates) : b d sort file | uniq -d But i need opossite of this. I have searched the forum and other places as well, but have found solution for everything except this variant of the problem. (3 Replies)
Discussion started by: necroman08
3 Replies
Login or Register to Ask a Question