Deleting multiple files with special character in file name from perforce - perforce

I have a directory having 90K files. Lets call the directory as "dir". Many of the filenames has special
character like #, # etc.
I am looking for a command how can I mark all those files as deleted in perforce.
Thanks,
Pradip

Special characters are translated to %nn escape codes in the depot namespace, so to operate on those files you need to use the escape code instead of the original character. (The exception to this rule p4 add, which takes the original unescaped name and then escapes it as part of opening the file.)
To operate on all of the files that contain escape codes for # (%40) and # (%23) anywhere in their path relative to dir, use wildcards:
p4 delete dir/...%40...
p4 delete dir/...%23...

Related

rename command for replacing text in filename from a certain point (character), but only up to, and maintaining the file extension

I've got a ton of files as follows
audiofile_drums_1-ktpcwybsh5c.wav
soundsample_drums_2-fghlkjy57sa.wav
noise_snippet_guitar_5-mxjtgqta3o1.wav
louder_flute_9-mdlsiqpfj6c.wav
I want to remove everything between and including the "-" and the .wav file extension, to be left with
audiofile_drums_1.wav
soundsample_drums_2.wav
noise_snippet_guitar_5.wav
louder_flute_9.wav
I've tried to do delete everything following and including the character "-" using
rename 's/-.*//' *
Which gives me
audiofile_drums_1
soundsample_drums_2
noise_snippet_guitar_5
louder_flute_9
And for lack of finding an easy way to rename all the files again, adding .wav the extension, I am hoping there is a slicker way to do this in one nifty command in one stage instead of 2.
Any suggestions?
Thanks
You can use rename 's/-[^\.]*\.wav$/\.wav/' *
The first part -[^\.]*\.wav$ searchs for a - followed by n chars that are not . followed by .wav and the end of filename. The end of filename and .wav is not strictly needed but it helps avoid renaming files you don't want to rename.
The /\.wav/ preserves the extension.
Please not that rename is not a standard utility, and is part of perl, so rename may not be available on every linux system.
This works in my specific case, but should work for any file extension.
rename -n 's/-.*(?=\.wav$)//' *
The command looks for all characters after and inclusive of the - symbol in the filename, then, using a positive lookahead** (?=\.wav$) to search for the characters (the file extension in this case) at the end of the filename (denoted by $, and replaces them with no characters (removing them).
** NOTE: A positive look ahead is a zero width assertion.
It will affect the match but it will not be included
in the replacement. (The '.wav' part will not be
erased)
In this example (?=\.wav$) is the positive lookahead. The dollar sign $, as in regex, denotes at the end of the line, so perfect for a file extension.

How to add file to .gitignore with \n in the filename

I just want to add file with file
name (file name contains \n) to .gitignore.
I try:
/file
name
/file\nname
file\
name
but have no luck.
Try
/file*name
* should match any characters.
Please tell me this is a homework assignment.
The .gitignore file uses a glob(7) style wildcard substitution so embedding a '*' should work. Linux really doesn't care about the filename spelling, so any character other than a '/' can go into a filename. On a command line be sure to use single-quotes (not double-quotes, mind you) so the shell doesn't get confused.
Reading the filenames from ls(1) and similar will split the name at the \n character because the glibc standard library is looking for newlines to find the end of a line of text. The '/' and '\n' characters are treated specially in many levels of the software stack, like the pathname of the file or splitting a buffer into lines or displaying the filename or letting awk(1), sed(1), and such scan a list of filenames.
But I agree with another poster: this is a bad idea. No, I take that back, it's a horrible idea. Long-term maintainability is going to be a nightmare.

Is there an alternative for the slash in a path?

I have an application which correctly escapes slashes ("/) in file names to avoid path traversal attacks.
The secret file has this path:
/tmp/secret.txt
I want to access this file by uploading a file with a special crafted file name (something like \/tmp\/secret.txt)
Is there any alternative syntax without the slashes which I can use so that Linux will read this file?
(I'm aware of URL encoding but as the escaping is done in the backend this has no use for me.)
No. The / is not allowed in a filename, no matter if it's escaped as \/ or not.
It is one out of only two characters that are not allowed in filenames, the other being \0.
This means that you obviously could use _tmp_secret.txt or -tmp-secret.txt, or replace the / in the path with any other character that you wish, to create a filename with a path "encoded into it". But in doing so, you can not encode pathnames that includes the chosen delimiter character in one or several of its path components and expect to decode it into the original pathname.
This is, by the way, how OpenBSD's ports system encodes filenames for patches to software. In (for example) /usr/ports/shells/fish/patches we find files with names like
patch-share_tools_create_manpage_completions_py
which comes from the pathname of a particular file in the fish shell source distribution (probably share/tools/create_manpage_completions.py). These pathnames are however never parsed, and the encoding is only there to create unique and somewhat intelligible filenames for the patches themselves. The real paths are included in the patch files.

How to rename a folder that contains smart quotes

I have a folder that was created automatically. The user unintentionally provided smart (curly) quotes as part of the name, and the process that sanitizes the inputs did not catch these. As a result, the folder name contains the smart quotes. For example:
this-is-my-folder’s-name-“Bob”
I'm now trying to rename/remove said folder on the command line, and none of the standard tricks for dealing with files/folders with special characters (enclosing in quotes, escaping the characters, trying to rename it by inode, etc.) are working. All result in:
mv: cannot move this-is-my-folder’s-name-“Bob” to this-is-my-folders-name-BOB: No such file or directory
Can anyone provide some advice as to how I can achieve this?
To get the name in a format you can copy-and-paste into your shell:
printf '%q\n' this*
...will print out the filename in a manner the shell will accept as valid input. This might look something like:
$'this-is-my-folder200\231s-name-200\234Bob200\235'
...which you can then use as an argument to mv:
mv $'this-is-my-folder200\231s-name-200\234Bob200\235' this-is-my-folders-name-BOB
Incidentally, if your operating system works the same way mine does (when running the test above), this would explain why using single-character globs such as ? for those characters didn't work: They're actually more than one byte long each!
You can use shell globbing token ? to match any single character, so matching the smart quotes using ? should do:
mv this-is-my-folder?s-name-?Bob? new_name
Here replacing the smart quotes with ? to match the file name.
There are several possibilities.
If an initial substring of the file name ending before the first quote is unique within the directory, then you can use filename completion to help you type an appropriate command. Type "mv" (without the quotes) and the unique initial substring, then press the TAB key to request filename completion. Bash will complete the filename with the correct characters, correctly escaped.
Use a graphical file browser. Then you can select the file to rename by clicking on it. (Details of how to proceed from there depend on the browser.) If you don't have a graphical terminal and can't get one, then you may be able to do the same with a text-mode browser such as Midnight Commander.
A simple glob built with the ? or * wildcard should be able to match the filename
Use a more complex glob to select the filename, and perhaps others with the same problem. Maybe something like *[^a-zA-Z0-9-]* would do. Use a pattern substitution to assign a new name. Something like this:
for f in *[^a-zA-Z0-9-]*; do
mv "$f" "${f//[^a-zA-Z0-9-]/}"
done
The substitution replaces all appearances of a characters that are not decimal digits, appercase or lowercase Latin letters, or hyphens with nothing (i.e. it strips them). Do take care before you use this, though, to make sure you're not going to make more changes than you intend to do.

What is wrong with this vim regular expression?

I have a list of files with extension .elf like this
file1.elf
file2.elf
file3.elf
I am trying to run them in shell with run command like run file1.elf >file1.log and get the result in a log file with file name with .log addition.
My list of file is very big. I am trying out a vim regular expression so it will match the file name eg file1 in file1.elf and use it to create name for the log file. I am trying out like this
s/\(\(\<\w\+\)\#<=\.elf\)/\1 >\2\.log/
Here i try to match a text which is proceeded by .elf and keep it in \1 , i expect the entrire file name to be in it and \2 i was hoping would just contain the file name minus extension. but this gives me
run file1 >file1.run i.e \1 dose not take the full file name, it has some how missed .elf extension. I can do \1\.elf to get proper result but i was wondering why the expression is not working as i expected?
You use \#<= in your match pattern. This is the positiv lookahead assertion. As per documentation (:help /\#<=1),
Matches with zero width if the preceding atom matches just before what follows
The important part is that it matches with zero width, this is what you are experiancing, the .elf (which follows) is matched but with zero widht, so that \1 does not contain the suffix .elf.
Instead, it would be easier to go with a
%s/\v(.*)\.elf$/run \1.elf > \1.log/
Here, I've used \v to turn on very magic (:help magic). With this turned on, you don't need al those backslashes when you use grouping parantheses.
Then there is (.*) to match and store the filename up until
\.elf$ which seems to be each files suffix.
In the substitution part, after the / I add the literal run followed by \1. \1 will be replaced by the stored filename (without .elf suffix).
The \#<= seems pointless and unneeded. Removing it gets you the desired behavior.

Resources