I use to run libreoffice headless for executing some macros from a bash script:
soffice --headless "$year_to_process"/"$initials".ods macro:///Standard.C69.MergeSaveClose
Before I do that, I need to check if the macro file c69.xba is present in the directory $HOME/.config/libreoffice/4/user/basic/Standard/.
The problem is that the digit '4' above seems to me to be version dependant. Another problem is that that digit doesn't match exactly the major version number returned by libreoffice --version, which outputs:
LibreOffice 5.4.5.1 40m0(Build:1)
What I have coded so far is:
# check the macro .config/libreoffice/*/user/basic/Standard/c69.xba is present
[ -f $HOME/.config/libreoffice/*/user/basic/Standard/c69.xba ] || {
echo "$cmd: missing file basic/Standard/c69.xba"
exit 1
}
using a '*' to match any version, but when a second directory will appear, as .config/libreoffice/{4,5}/user/basic/Standard, my code will no longer work.
My question is: how can I get (from the command line) the correct path to the directory containing the macros used by the current version of libreoffice, without using a '*'?
Starting from the comment above of Aserre about the arbitrary character of the path to the configuration of LibreOffice, I chose to select the most recently created profile of LibreOffice, using the -t option of the ls command. So I found next solution to work:
# check the macro .config/libreoffice/*/user/basic/Standard/c69.xba is present
path=$(ls -dt "$HOME"/.config/libreoffice/* | head -n1) # take only first line of output of ls -dt
[ -f "$path/user/basic/Standard/c69.xba" ] || {
echo "$cmd: missing file basic/Standard/c69.xba"
exit 1
}
Related
My workflow uses 3 indirect files.
The indirect files can have one or more file names.
Let's say all 3 indirect files have 2 file names each.
Indirect_file1 has (file1,file2)
Indirect_file2 has (filea,fileb)
Indirect_file3 has (filex,filey)
My workflow should run in sequence.
First sequence (file1,filea,filex)
Second sequence (file2,fileb,filey)
we are on Linux environment, so i guess it can be done using shell script
Any pointers will be appreciated.
Thanks in Advance.
This should work -
in informatica session, modify input type to 'Command'
in informatica session, change command type to 'Command generating file List'
for first worfklow set the command like this 'cut -d ',' file -f1' if your delimiter is comma.
for second worfklow set the command like this 'cut -d ',' file -f2' if your delimiter is comma.
You might want to make small work packages first before processing. When the workflow takes a long time it is easier to (re-)start new processes.
You can start with something like this:
# Step 1, move the current set to temporary folder
combine_dir=/tmp/combine
mkdir "${combine_dir}"
mv Indirect_file1 "${combine_dir}"
mv Indirect_file2 "${combine_dir}"
mv Indirect_file3 "${combine_dir}"
# Step 2, construct work packages in other tmp dir
workload_dir=/tmp/workload
mkdir "${workload_dir}"
for file in Indirect_file1 Indirect_file2 Indirect_file3; do
loadnr=1
for work in $(grep -Eo '[^(,)]*' "${file}"); do
echo "${work}" >> ${workload_dir}/sequence${loadnr}
((loadnr++))
done
done
# The sequenceXXX files have been generated with one file on each line.
# When you must have it like (file1,filea,filex), change above loop.
# Now files are ready to be processed. Move them to some dir where files will be handled.
# Please cleanup temporary files
I am trying automate a redundant deployment process in my project. In order to achieve that I am trying to get the difference between two branches using "git diff" -- Someway and I am able to achieve that using the following command.
git diff <BRANCH_NAME1> -- common_folder_name/ <BRANCH_NAME2> -- common_folder_name/ > toStoreResponse.txt`
Now the response that I get, looks something like below:
diff --git a/cmc-database/common/readme.txt b/cmc-database/common/readme.txt
index 7820f3d..5a0e484 100644
--- a/cmc-database/common/readme.txt
+++ b/cmc-database/common/readme.txt
## -1 +1,5 ##
-This folder contains common database scripts.
\ No newline at end of file
+This folder contains common database scripts.
+TEST STTESA
\ No newline at end of file
So here in the above response only line/text that is a new line or the difference between the two branches is TEST STTESA and I want to store only that much of text in some different text file using shell / git way.
i.e a file named readme.txt which will only contain TEST STTESA content.
Work around Solution:
I have found a workaround to filter the response - but however it is not 100% what I am looking for. Command looks like below:
git diff <Branch_Name1> -- common-directory/ <Branch_Name2> -- common-directory/ | grep -v common-directory | grep -v index | grep -v # | grep -v \\
The above command returns below response:
-This folder contains common database scripts.
+This folder contains common database scripts.
+TEST STTESA
But I want to be able to store only the difference which is TEST STTESA
As you can easily realize, your solution won't work every time. The grep -v parts make it unportable.
Here is a "step0" solution : You want to match lines that start with a "+" or a "-" and then neither a "+" nor a "-". Use grep for that !
git diff ... | grep "^+[^+]\|^-[^-]"
Some explanation :
First, the \| part in the middle is an "or" statement.
Then, each side starts with a ^ which refers to the beginning of the line. And finally, after the first character, we want to reject some characters, using the [^...] syntax.
The line above translates to English as "Run the diff, and find all the lines that either start with a +, followed by something that is not a +, OR start with a -, followed by something that is not a -.
This will not work properly if you remove a line that started with a -. Nor if you add a line that starts with a +.
For such scenarii, I would tinkle with git diff --color and grep some [32m for the fun.
--diff-filter=[ACDMRTUXB*]
Select only files that are
A Added
C Copied
D Deleted
M Modified
R Renamed
T have their type (mode) changed
U Unmerged
X Unknown
B have had their pairing Broken
and * All-or-none
We were assigned a project that works with various file. The code in question is this:
if [[ -f $first_arg ]]; then
open_file $first_arg
elif [[ -d $first_arg ]]; then
search_directory $first_arg
.....
It works fine with just regular files, but it comes into the second condition if I run the script like this (with the ~/.) :
./script01.sh ~/.config
So I'm wondering what goes on when bash checks -f and -d, what is considered a directory or file and what is not anymore.
~/.config is quite commonly a directory as Joe has suggested in the comments.
As to what goes on, bash apparently calls stat(2) on the file in question which returns a corresponding structure including st_mode field. Details for that are in inode(7):
The stat.st_mode field (for statx(2), the statx.stx_mode field) con‐
tains the file type and mode.
Namely:
The following mask values are defined for the file type:
...
S_IFREG 0100000 regular file
...
S_IFDIR 0040000 directory
All that is left is to check which bits are set.
Problem :
I want to get the latest csv file in the downloads folder by typing $LATEST. When I dereference $LATEST I want to see the last csv file put in there.
What I have tried :
'ls -t $DL/*.csv | head -1' (this works)
export $LATEST='ls -t $DL/*.csv | head -1'
The problem with 2. is it always returns the latest file at the time export is run. (e.g. old.csv) When I add a new file (e.g. new.csv) I want $LATEST to show new.csv not old.csv.
Variables don't track changes in system state. They have values. Those values persist until you change them. If you want variable-like access to the current state, use a function. Example:
latest() {
ls -t $DL/*.csv | head -1
}
echo "The latest file is $(latest)"
if [ "new.csv" = "$(latest)" ]; then
echo "Hooray, new is latest!"
fi
A side benefit is that functions can take arguments. For example, if you wanted to make your latest function generic, but with reasonable defaults, you could do:
latest() {
ls -t ${1:-$DL}/*.csv | head -${2:-1}
}
latest # show the 1 latest file from $DL directory
latest /tmp # show the 1 latest file from /tmp
latest /tmp 5 # show the five latest files from /tmp
In this case
The environment variable won't get updated automatically, it just stores the value. But you can define a function that will evaluate the expression from 1. every time your call it:
function latest {
ls -t $DL/*.csv | head -1
}
Now if you put it in your ~/.bashrc and reload, you can call latest to evaluate the expression and get the result.
If you can use zsh, it's much easier:
$ latest () { print "$DL"/*.csv(om[1]) }
The glob qualifier om sorts the expansion of "$DL"/*.csv by date; the [1] selects on the first element of the sorted expansion.
This avoids any concern about filenames containing newlines, which is the reason why parsing the output of ls should be avoided in theory.
How do you test if compiled code returns the expected output or fails as expected?
I have worked out a working example below, but it is not easily extendable. Every additional test would require additional nesting parentheses. Of course I could split this into other files, but do you have any suggestions on how to improve this?. Also I'm planning to use this from make test stanza in a makefile, so I do not expect other people to install something that isn't installed by default, just for testing it. And stdout should also remain interleaved with stderr.
simplified example:
./testFoo || echo execution failed
./testBar && echo expected failure
(./testBaz && (./testBaz 2>&1 | cmp -s - foo.tst && ( ./testFoo && echo and so on
|| echo testFoo's execution failed )|| echo testBaz's does not match )
|| echo testBaz's execution failed
my current tester looks like this (for one test):
\#!/bin/bash
compiler1 $1 && (compiler2 -E --make $(echo $1 | sed 's/^\(.\)\(.*\)\..*$/\l\1\2/') && (./$(echo $1 | sed 's/^\(.\)\(.*\)\..*$/\l\1\2/') || echo execution failed) || less $(echo $1 | sed 's/^\(.\)\(.*\)\..*$/\l\1\2/').err) || echo compile failed
I suggest to start looking for patterns here. For example, you could use the file name as the pattern and then create some additional files that encode the expected result.
You can then use a simple script to run the command and verify the result (instead of repeating the test code again and again).
For example, a file testFoo.exec with the content 0 means that it must succeed (or at least return with 0) while testBar.exec would contain 1.
textBaz.out would then contain the expected output. You don't need to call testBaz several times; you can redirect the output in the first call and then look at $? to see if the call succeeded or not. If it did, then you can directly verify the output (without starting the command again).
My own simple minded test harness works like this:
every test is represented by a bash script with an extension .test - these all live in the same directory
when I create a test, I run the test script and examine the output
carefully, if it looks good it goes into a directory called good_results, in a file with the same name as the test that generated it
the main testing script finds all the .test scripts and executes each of them in turn, producing a temporary output file. This is diff'd with the
matching file in the good_results directory and any differences reported
Itv took me about half an hour to write this and get it working, but it has proved invaluable!