I'm trying to parse a lattice with grep and save the output in a variable in a cshell script. But somehow I always get the error message "Illegal variable name" when adding the FILE_IN_B variable. I tried different spacings after the variables name and also tried $() ,or %.* ,instead of sed to remove the last four letters but neither works in cshell. Also tried setting the declaration in "", to no avail. I'm really desperate here...
#!/bin/csh
set FILE_IN = file.ext
set SOURCE = home/Developer
set FILE_IN_B=`sed '/.\{4\}$//' >>> "$FILE_IN"`.lat
set REC = `grep -C 1 'I=11' "$SOURCE/Lattice/$FILE_IN_B" | cut -d ' ' -f 3 | cut -d= -f 2| sed 's/sp//'`
csh has some built-in variable manipulation, including one meant for extension removal:
% set FILE_IN=file.ext
% set FILE_IN_B="${FILE_IN:r}.lat"
% echo "$FILE_IN_B"
file.lat
If sed is required then printf can be used as the standard input, similar to portable sh:
% set FILE_IN=file.ext
% set FILE_IN_B=`printf %s "$FILE_IN" | sed 's/.\{4\}$//'`.lat
% echo "$FILE_IN_B"
file.lat
Related
I am trying to extract two #define values from a C header file to use them in a shell script. So I use grep to find them and then print them. However, the variables are sometimes empty.
// main.h
#define DEVICE_NO 1
#define FW_VERSION 1
And the script file is
#!/bin/bash -
read_version()
{
echo $(grep $1 "$projectdir/Inc/main.h" | cut -d ' ' -f 3-)
}
device_no=$(read_version "DEVICE_NO")
fw_version=$(read_version "FW_VERSION")
echo "DEVICE_NO = $device_no, FW_VERSION = $fw_version"
So the expectation is that the output to be:
DEVICE_NO = 1, FW_VERSION = 1
but sometimes it turns to be
5
DEVICE_NO = , FW_VERSION = 1
It randomly misses one or both of the values. The header file does not change so it's not coming from there.
UPDATE
As commented I thought maybe the windows line ending is a problem so I piped the output to tr and removed \r but it did not make any difference. also tried var=$(grep FW_VERSION file); $(echo ${var//[$'\t\r\n']} | cut ... to no avail.
I tried using awk instead of cut but got the same result.
I redirected the error inside the command to the standard output ($(grep $1 file | cut -d ' ' -f 3 2>&1) but did not get any extra information
I split the command to a grep part and a cut, the grep never misses but the output of cut randomly gives an empty string as output.
I still have no idea where that 5 is coming from, there is nothing in cut or awk manuals that throws a 5 to either standard output or stderr.
I have a variable var=/usr/local/bin/test/exec
Now i have to remove last 2 path components in the above variable say:
var=/usr/local/bin/
After removing the last 2 strings I have to use this variable 'var' in a shell loop.
I tried:
var='/usr/local/bin/test/exec'
echo ${var#$(dirname "$(dirname "$s")")/}
Output:
test/exec
I am getting the truncated part as output, but I was expecting the rest of the part, not the truncated part.
You may be interested in the shell's internal substring processing operators: %, %%, # and##. Observe:
#!/bin/sh
var=/usr/local/bin/test/exec
# use shell substring processing to cut the variable down to size:
var="${var%/*}"
var="${var%/*}"
echo "$var"
# Manipulate the resulting string in a loop
for i in 1 2 3
do echo "${var}${i}"
done
OK after some googling i have found the solution for this:
var1="$(echo $var | cut -d '/' -f-4)"
If you don't know the field count, there is a standard awk solution. However, I'll show another trick using rev
var='/usr/local/bin/test/exec'; echo $var | rev | cut -d/ -f3- | rev
will give
/usr/local/bin
You can try this method also
var=/usr/local/bin/test/exec
sed 's_\(.*\)/.*/.*$_\1_' <<< $var
Another Method
sed 's_\(.*\)\(/.*\)\{2\}$_\1_' <<< $var
Output:
/usr/local/bin
I'm trying to extract the file name without the extension from a directory full of files. Here is the code that I'm using:
foreach file (*)
set extPos=`echo $file | awk '{print index($0,".")}'`
set fname = `echo $file | awk '{print substr($0,0,$extPos)}'`
echo $file
echo $extPos
echo $fname
end
And these are the results I'm receiving:
hodorrr.png
8
testfile1.txt
10
testfile2.txt
10
testfile3.txt
10
wtf.tiff
4
So as you can see the substrings are blank, does anyone know why this is?
The usage of substr can be confusing and inconsistent with other versions of substr.
To fix your immediate problem, try
set fname = `echo $file | awk '{print substr($0,1,'"$extPos"')}'`
To eliminate the relatively expensive calculation of $extPos with multiple processes, you can get fname from file all in 1 awk process with
file=testfile1.txt
#not needed set extPos=`echo $file | awk '{print index($0,".")}'`
set fname = `echo $file | awk '{print substr($0,1,index($0,".")-1)}'`
echo "fname=" $fname
testfile1
So note that substr doesn't use 0 for it's address for the first position in a string (but uses 1 (thank you awk gods!;-) AND that you can nest function calls (like index()) inside the parameter list of another function.
Of course the usual warnings like friends don't let friend code in csh still apply, but sometime organization inertia is too much to overcome!
IHTH
If I understand what you're trying to do, you don't need awk. csh has built-in features to extract the root or extension from a file name.
% foreach file ( this.txt that.dat another.blah )
foreach? echo "file = '$file', root = '$file:r', extension = '$file:e'"
foreach? end
file = 'this.txt', root = 'this', extension = 'txt'
file = 'that.dat', root = 'that', extension = 'dat'
file = 'another.blah', root = 'another', extension = 'blah'
%
The modifiers are documented in the tcsh man page under History substitution, but they also apply to variable substitution.
(If you decide to switch to bash, it has similar features, but they're not quite as convenient.)
Im trying to make a script that takes a .txt file containing lines
like:
davda103:David:Davidsson:800104-1234:TNCCC_1:TDDB46 TDDB80:
and then sort them etc. Thats just the background my problem lies here:
#!/bin/sh -x
cat $1 |
while read a
do
testsak = `echo $a | cut -f 1 -d :`; <---**
echo $testsak;
done
Where the arrow is, when I try to run this code I get some kind of weird error.
+ read a
+ cut -f+ echo 1 -d :davda103:David:Davidsson:800104-1234:TNCCC_1:TDDB46
TDDB80:
+ testsak = davda103
scriptTest.sh: testsak: Det går inte att hitta
+ echo
(I have my linux in swedish because school -.-) Anyways that error just says that it cant find... something. Any ideas what could be causing my problem?
You have extra spaces around the assignment operator, remove them:
testsak=`echo $a | cut -f 1 -d :`; <---**
The spaces around the equal sign
testsak = `echo $a | cut -f 1 -d :`; <---**
causes bash to interpret this as a command testak with arguments = and the result of the command substitution. Removing the spaces will fix the immediate error.
A much more efficient way to extract the value from a is to let read do it (and use input redirection instead of cat):
while IFS=: read testak the_rest; do
echo $testak
done < "$1"
I am going though some growing pains with Unix. My question:
I want to be able to print all my user defined variables in my shell. Let say I do the following in the shell:
$ x=9
$ y="Help"
$ z=-18
$ R="My 4th variable"
How would I go about printing:
x y z R
You should record your variables first at runtime with set, then compare it later to see which variables were added. Example:
#!/bin/bash
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/previous.txt
a=1234
b=1234
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/now.txt
comm -13 /tmp/previous.txt /tmp/now.txt
Output:
a
b
PIPESTATUS
Notice that there are still other variables produced by the shell but is not declared by the user. You can filter them with grep -v. It depends on the shell as well.
Add: Grep and cut could simply be just one sed a well: sed -n 's/^\([^[:space:]]\+\)=.*/\1/p'
Type set:
$ set
Apple_PubSub_Socket_Render=/tmp/launch-jiNTOC/Render
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="2" [2]="51" [3]="1" [4]="release" [5]="x86_64-apple-darwin13")
BASH_VERSION='3.2.51(1)-release'
COCOS2DROOT=/Users/andy/Source/cocos2d
COLUMNS=80
DIRSTACK=()
...
(Oh, and BTW, you appear to have your variable syntax incorrect as you assign, say, A but print $A)
If variables are exported then you can use env command in Unix.