how to handle files/directories with '#' in perforce - perforce

I have some folders with '#' in it.
I can't seem to make it work
>cd fmsn_adc_vs_cdc_clock_reset_integrity#fmsn_adc_vs
>p4 rec -n ...
//depot/icm/proj/i10soc2/fmsn_lib/cdc/dev/fmsn_adc_vs/results/fmsn_adc_vs_cdc/consolidated_reports/fmsn_adc_vs_cdc_clock_reset_integrity%40fmsn_adc_vs/spyglass.log - can't reconcile filename with wildcards [##%*]. Use -f to force reconcile.
... - no file(s) to reconcile.
>cd .. >p4 rec -n 'fmsn_adc_vs_cdc_clock_reset_integrity#fmsn_adc_vs/...'
Invalid changelist/client/label/date '#fmsn_adc_vs/...'.
No file(s) to reconcile.
How can we handle files/directories with '#' ?
Is there any documentation I can refer to?
Thanks in advance.

The first error message gives you the exact answer:
Use -f to force reconcile.
Just add -f to the command you tried the first time:
p4 rec -n -f ...
This will automatically translate the # to %40 in the depot path when it opens the file for add. From that point on, if you need to refer to that file by name, use %40 in place of #. It will still have the # in its local path.

Related

Remove the last X files of a directory

In colab, I have unzip a file, but now there is too much files in the directory according to the colab's setup. Is there a command line to remove the last x files of a directory?
I know I can remove all the files from this repository with rm -rf *, but I just want to remove for instance the last 100 files of the repository.
Try globing or better REGEX.
The most easy way is with globing you use the star * and some differentiation example: rm *.txt # will delete all files that end with .txt or rm document*.local # will delete all files which start with document and end with .local
The better wey is searching files by attribut and executing command on the result but is a bit complex to explain so check this out.
https://www.cyberciti.biz/faq/linux-unix-how-to-find-and-remove-files/
Using a shell array and parameter expansion:
all_files=(*)
printf '%s\n' "${all_files[#]: -100}" | nl
#rm "${all_files[#]: -100}"
Uncomment the last line if it looks like the correct list of files to delete.
The space between the colon and the minus sign is required to disambiguate from another form of parameter expansion.
Ref: 3.5.3 Shell Parameter Expansion

Removing changing pattern from filenames in directory in Linux

I have a directory containing files following the following naming convention:
Label_0000_AA.gz
Label_0001_BB.gz
Label_0002_CC.gz
...
All I want to do is to rename these files so that the _#### number pattern is removed, resulting in:
Label_AA.gz
Label_BB.gz
Label_CC.gz
...
but only up to a certain number. E.g.: I may have 10000 files but might only want to remove the pattern in the first 3000. Would this be possible using something like bash?
If you don't have prename or rename -
(assuming the names are consistent)
for f in Label_[0-9][0-9][0-9][0-9]_[A-Z][A-Z].gz
do mv "$f" "${f//_[0-9][0-9][0-9][0-9]/}"
done
To just do a certain range -
for n in {0000..2999}
do for f in Label_${n}_??.gz
do mv $f ${f//_$n/}
done
done
You're sure there are not collisions?
If you can name the pattern you want to change/remove in a regex you can use the command prename:
prename 's/_[0-3][[:digit:]]{3}_/_/g' Label_*.gz
This regex would only remove numbers 0000-3999.
Using the flag -n does a "dry-run" and shows what it would do.
Edit: Thanks #KamilCuk to remind me about two renames. I made it clear and changed the name to prename.

string manipulation of Directory structure

Scenario: I have a script but no idea where I am in the directory tree, I need to resolve back to the nearest known location UPROC[something]
What I have so far:
I have a script running in a directory for example:
/home/jim/query/UPROCL/test/bob/dircut.sh
now the only constant in this is that the Directory I want will begin with UPROC... maybe not UPROCL but definitely UPROC
So I have written the following:
#!/bin/bash
#Absolute path for this script
SCRIPT=$(readlink -f "$0")
echo $SCRIPT
#Gets Path of script without script name
SCRIPTPATH=$(dirname "$SCRIPT")
echo $SCRIPTPATH
#Cuts everything after UPROC(.* is wildcard)/
CUTDOWN=$(sed 's/\(UPROC.*\/\).*/\1/' <<< $SCRIPTPATH)
echo $CUTDOWN
The only problem is that it output is:
/home/jim/query/UPROCL/test/bob/dircut.sh
/home/jim/query/UPROCL/test/bob
/home/jim/query/UPROCL/test/
Can some tell me what is wrong with my sed command as it is not cutting down to
/home/jim/query/UPROCL/
Because * is greedy. You want to be more selective about what characters are allowed following "UPROC" -- any non-slash
Not
sed 's/\(UPROC.*\/\).*/\1/'
but
sed -r 's,(UPROC[^/]*/).*,\1,'
Using different delimiters for the s/// command reduces the "leaning toothpick" problem.
Because the .* in the () is matching to the / at the end of test/.
You need [^/]* instead of . to not match any slashes.
When you want to know in which directory you are, why don't use pwd?
One thing which might be useful: the command pwd shows the value of the environment variable PWD (uppercase). In case you want to use the current directory as a value, you might use this.

Recursive grep with include giving incorrect results for current folder

I have created a test directory structure:
t1.html
t2.php
a/t1.html
a/t2.php
b/t1.html
b/t2.php
All files contain the string "HELLO".
The following commands are run from the root folder above:
> grep -r "HELLO" *
b/t1.html:HELLO
b/t2.php:HELLO
c/t1.html:HELLO
c/t2.php:HELLO
t1.html:HELLO
t2.php:HELLO
> grep -r --include=*.html "HELLO" *
b/t1.html:HELLO
c/t1.html:HELLO
t2.php:HELLO
Why is it including the correct .html files from the sub-directories, but the .php file from the current directory?
If I pop up a level to the directory above my whole structure, then it gives following result:
grep -r --include=*.html "HELLO" *
a/t1.html:HELLO
a/c/t1.html:HELLO
a/b/t1.html:HELLO
This is what I expected when ran from within my structure.
I assume I can achieve the goal using find+grep together, but I thought this was valid usage of grep.
Thanks for any help.
Andy
Use a dot instead of the asterisk:
grep -r HELLO .
Asterisk gets evaluated by the shell and replaced with the list of all the files in the current directory (whose names don't start with a dot). All of them are then grepped recursively.

linux batch rename directories and strip # character from name

i have a directory with a lot of subdirectories with a # infront of them:
#adhasdk
#ad18237
I want to rename them all and remove the # caracter
I tried to do:
rename -n `s/#//g` *
but didn't seem to work.
-bash: s/#//g: No such file or directory
Any ideas on this.
Thanks
Just use
$ rename 's/^#//' *
use -n just to check that what you think it would happen really happens.
In you example you have the clue about the wrong quotes used (backticks) in the error message
-bash: s/#//g: No such file or directory
bash is trying to execute a command named s/#//g.
No that using g (global) and not anchoring the regular expression you will replace any #, not just the one in the first position.
I don't know whether it's just a typo when you typed it here, but that "rename" command should work if:
you leave off the "-n" and
you quote the substitution with regular single-quotes and not back-quotes
The "-n" tells it to not really do anything. The back-quotes are just wrong (they mean something but not what you want here).
The problem is that you use backticks (`). You should use normal quotes:
rename -n 's/#//g' *
for DIR in \#*/
do
echo mv "$DIR" "${DIR/#\#/}"
done
I had to rename all folders inside a given folder. Each folder name had some text inside round braces. The following command removed the round braces from all folder names:
rename 's/(.+)//' *
Some distros doesn't support regexp in rename. You have to install prename. Even more, sometimes you can't install prename and you have to install gprename to have binary prename.
If you have 'prename' then just change backtick character " ` " to single quote and everything should work.
So the solution should be:
prename -n 's/#//g' *
or
prename -n 'y/#//' *

Resources