help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] how to translate one file


From: lina
Subject: Re: [Help-bash] how to translate one file
Date: Wed, 04 Jan 2012 00:43:49 +0800
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111114 Icedove/3.1.16

On Tuesday 03,January,2012 11:43 PM, Eric Blake wrote:
On 01/03/2012 08:15 AM, lina wrote:
When I derive it to a field problem,

$ cat dm_1.xpm | while read line ; do IFS=$'\n' ; if [ ${#line} == 30 ];
then echo $line ; fi ; done
Useless use of cat.  Use of $'\n', as well as == within [, are bash
extensions; there's talk of standardizing both of them in the next
version of POSIX, but they isn't portable yet.  I have no idea why you
are changing $IFS, nor why you forget to reset it later, as it doesn't
affect anything in your 2-line sample; but assuming it was important,
I'll keep it as you wrote it.  Also, you had insufficient quoting; you
probably want echo "$line" rather than echo $line.  I would have written
this as:

while read line; do
   IFS='
'
   if [ ${#line} = 30 ]; then
     echo "$line";
   fi
done<  dm_1.xpm

if I use:
$ cat dm_1.xpm | while read line ; do IFS=$'\n' ; if [ ${#line} == 30 -a
${line:0:1}== '"' ]; then echo $line ; fi ; done
bash: [: too many arguments
That's because you are invoking [ incorrectly - operators MUST be
separated by spaces, but since you joined ${line:0:1} and == as a single
argument, you ended up causing a syntax error.  Also, [ -a is not
portable; POSIX explicitly recommends against using it.  And ${line:0:1}
is a bash extension; you can portably get the same effect of comparing
the first byte via a case statement.  I think you either want to fix
your version:

cat dm_1.xpm | while read line ; do IFS=$'\n' ;
   if [ ${#line} == 30 -a ${line:0:1} == '"' ]; then echo $line ; fi ; done
Thanks,  the -a  is not efficient here, print out more than expected.
or to use this portable alternative:

while read line; do
   if [ ${#line} = 30 ]; then
     case $line in \") echo "$line" ;; esac
case $line in \"*) can print the expected results well. ^_^
May I ask here why you use ";;" not one ; .
   fi
done<  dm_1.xpm

Or, do your entire processing in sed instead of a shell loop; this
script filters out and prints only lines which meet two simultaneous
regex - a line that starts with ", and a line that has exactly 30
characters:

sed -n '/^"/ { /^.\{30\}$/ p; }' dm_1.xpm





reply via email to

[Prev in Thread] Current Thread [Next in Thread]