GDB: How remove/replace pattern from a variable? - sed

I found the similar post here and here. But those solution seems like replacing the pattern from a file, not from a variable.
I have a function in a gdb script, which takes an address of a structure as $arg0 and prints the fields of that structure like following,
Function:
define call_rb_node
set $rb_left_child= (*(struct rb_node*)$arg0).rb_left
set $rb_right_child= (*(struct rb_node*)$arg0).rb_right
# printing fields
p $rb_left_child
p $rb_right_child
end
Output:
$1 = (struct rb_node *) 0xffff888236960f88
$2 = (struct rb_node *) 0xffff888236be92c8
I want to remove this (struct rb_node *) from both $rb_left_child and $rb_right_child. I want my output to be like
$rb_left_child = 0xffff888236960f88
$rb_right_child = 0xffff888236be92c8
I was trying to use sed (don't know if I have any other options) to do that, but it's not working, I tried the following approach, but it's not working
define call_rb_node
set $rb_left_child= (*(struct rb_node*)$arg0).rb_left
set $rb_right_child= (*(struct rb_node*)$arg0).rb_right
set $rb_left_child = $(sed /(struct rb_node *) /d $rb_left_child)
# printing fields
p $rb_left_child
end
I'm getting the following error
Error in sourced command file:
No symbol "sed" in current context.
I replace the line like this,
shell echo set \$left_child=$(sed '/(struct rb_node *) /d' "$rb_left_child") > gdb.tmp
source gdb.tmp
p $left_child
but keep getting the following error,
Error in sourced command file: gdb.tmp:1: Error in sourced command file:
A syntax error in expression, near `'.
please help.

Related

Having trouble conditionally moving files based on their names

I am trying to write a script that will auto sort files based on the 7th and 8th digit in their name. I get the following error: "Argument must be a string scalar or character vector". Error is coming from line 16:
Argument must be a string scalar or character vector.
Error in sort_files (line 16)
movefile (filelist(i), DirOut)
Here's the code:
DirIn = 'C:\Folder\Experiment' %set incoming directory
DirOut = 'C:\Folder\Experiment\1'
eval(['filelist=dir(''' DirIn '/*.wav'')']) %get file list
for i = 1:length(filelist);
Filename = filelist(i).name
name = strsplit(Filename, '_');
newStr = extractBetween(name,7,8);
if strcmp(newStr,'01')
movefile (filelist(i), DirOut)
end
end
Also, I am trying to make the file folder conditional so that if the 10-11 digits are 02 the file goes to DirOut/02 etc.
First, try avoid using the eval function, it is pretty much dreaded as slow and hard to understand. Specially if you need to create variables. Instead do this:
filelist = dir(fullfile(DirIn,'*.wav'));
Second, the passage:
name = strsplit(Filename, '_');
Makes name a list, so you can access name{1} or possibly name{2}. Each of these are strings. But name isn't a string, it is a list. extractBetween requires a string as an input. That is why you are getting this problem. But note that you could have simply done:
newStr = name(7:8);
If name was a string, which in Matlab is a char array.
EDIT:
Since it has been now claimed that the error occurs on movefile (filelist(i), DirOut), the likely cause is because filelist(i) is a struct. Wheres a filena name (char array) should have been given at input. The solution should be replacing this line with:
movefile(fullfile(filelist(i).folder, filelist(i).name), DirOut)
Now, if you want to number the output folders too, you can do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,name(7:8)])
This will move a file to /DirOut/01. If you wanted /DirOut/1, you could do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,int2str(str2num(name(7:8)))])

How to combine CLI arguments as variables within a perl script

I am trying to write a script that basically executes a cli command like:
snmpget -v 1 -c xxxxxx-Ovq xx.xx.xx.xxx .1.3.6.1.2.1.1.8.0
where xxxxx is a password and xx.xx.xx.xxx and IP that normally returns:
49:22:12:15.00
My script is:
#!/usr/local/bin/perl
#snmpget -v 1 -c xxxxx -Ovq xx.xx.xx.xxx .1.3.6.1.2.1.1.8.0
$SNMP_GET_CMD = "snmpget -v1 -c xxxxx-Ovq";
$SNMP_TARGET = "xx.xx.xx.xxx";
my $sysORLastChange = '${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0';
chomp($sysORLastChange);
print("${SNMP_TARGET} as an Input Line Reading of ${sysORLastChange}\n");
and the output is:
xx.xx.xx.xxx as an Input Line Reading of ${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0
It should return the following:
xx.xx.xx.xxx as an Input Line Reading of 49:22:12:15.00
Is there any problem with the syntax i used in the script?
In Perl, use double-quotes to interpolate another variable into a string. When you define $sysORLastChange using other variables within a single-quoted string like this:
my $sysORLastChange = '${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0';
...the string is being assigned verbatim (ie. the inner variables aren't being expanded).
To correct this, assign to the variable using double-quotes, which will interpolate the inner variables into their values:
my $sysORLastChange = "${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0";
If you want to actually execute the string, you can use the qx() operator, aka the "backtick" style quotes:
my $sysORLastChange = qx(${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0);
# or...
my $sysORLastChange = `${SNMP_GET_CMD} ${SNMP_TARGET} .1.3.6.1.2.1.1.8.0`;
See Perl Quote and Quote-like Operators in perlop.

MATLAB copyfile error: argument must contain a string

So I have a pretty simple problem I'm trying to solve. I want to create a backup of a file in MATLAB.
Here is my code (I am starting this script from my current directory):
backup_dir=strcat(pwd,'/backups/');
cd('../../source_destination/');
source_dir=pwd;
cd(backup_dir);
source_files=strcat(source_dir,'/*.m');
source_file_list=dir(source_files);
source_file_names={source_file_list.name}';
for i=1:numel(source_file_names)
source_file=strcat(source_dir,'/',source_file_names(i));
backup_file=strcat(backup_dir,source_file_names(i));
copyfile(source_file,backup_file);
end
Running this gives me the error:
Error using copyfile
Argument must contain a string.
However, when I actually examine source_file and backup_file, both variables return a valid string (enclosed by ' ') and both strings do point to a valid file:
>> source_file
source_file =
'/Users/me/mydir/cool/source_destination/archive.m'
>> backup_file
backup_file =
'/Users/me/mydir/cool/world/scripts/backups/archive.m'
Also, the actual content of source_file_list is valid.
So why would I be getting this error?
You need to dereference the cell array contents with curly braces, otherwise strcat returns a cell array of strings:
for i=1:numel(source_file_names)
source_file=strcat(source_dir,'/',source_file_names{i});
backup_file=strcat(backup_dir,source_file_names{i});
copyfile(source_file,backup_file);
end

perl script for find and replace or insert if blank

I am trying to write a perl script to search a config file for the following line:
remote_phonebook.data.1.url =
and do 1 of 2 things:
if the right of side of the = is blank add someString
if there is something there, replace anything there with someString
This will insert just fine:
s/remote_phonebook\.data\.1\.url = /remote_phonebook.data.1.url = someString/;
however if someString already exists, it will append it to look like this:
remote_phonebook.data.1.url = someString someString
This will replace just fine if someString already exists, but wont insert if its blank.
s/remote_phonebook\.data\.1\.url = someString/remote_phonebook.data.1.url = someString/;
.* is your friend, here. It means "match 0 or more (*) of any character (.)":
s/remote_phonebook\.data\.1\.url =.*/remote_phonebook.data.1.url = someString/;
So whether or not there is anything after the =, you'll end up with the contents you want. To make sure that you're matching from the start of the line (so "xxxremote_phonebook..." won't match), and to allow for more (or less) space before the "=", I'd use:
s/^remote_phonebook\.data\.1\.url\s*=.*/remote_phonebook.data.1.url = someString/;
s/^\s*remote_phonebook\.data\.1\.url\s*=\K.*/someString/;
The .* will match anything up to a newline.
The \K makes it so you don't have to repeat everything.

I can't get this simple LLDB alias to work

I want to create an LLDB alias ps, such that
ps foo
becomes
print [self foo]
I've been watching the LLDB talk (WWDC session 321 on iTunes), and based on that, it looks like the alias to do that should be this one:
command alias ps print [ self %1 ]
but it doesn't work. Here I've given my app delegate a simple "count" method that returns an integer:
(lldb) command alias ps print [ self %1 ]
(lldb) ps count
error: invalid operands to binary expression ('AppDelegate *' and 'int')
error: 1 errors parsing expression
(lldb) print [ self count ]
(int) $6 = 2
(lldb)
What am I missing?
It seems arguments (%1, %2, etc) doesn't work to alias an expression. There is a workaround by using a regular expression instead:
command regex ps 's/(.+)/print [self %1]/'
It makes an alias ps for the above regular expression:
(lldb) ps firstName
print [self firstName]
(NSString *) $1 = 0x06e64e20 #"John"
However this will last till the debug session ends. You'll have to enter it again for the next debug session. If you want your ps command to persist through debug sessions, you'll have to save it in your ~/.lldbinit file (if it doesn't exist, create one).
See llvm blog for more deails about regex command.